You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
4.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#程序类
class Program:
def __init__(self):
self.instrList = [] #指令列表其中的元素或者是Instruction或者是Loop
#将中间表示转化为代码并输出到文件
def emit(self, stream, cnt):
for instr in self.instrList:
instr.emit(stream, cnt)
return cnt
#循环类
class Loop:
def __init__(self, iterator, times):
self.iter = iterator #循环变量,是一个寄存器
self.times = times #循环次数,是一个寄存器
self.instrList = [] #指令列表其中的元素是Instruction或Loop应该有如下的形式
'''
beq i, n, out
loop:
[loop body]
addi i, i, 1
bne i, n, loop
out:
'''
def emit(self, stream, cnt):
cnt = cnt + 1
for i in range(len(self.instrList)):
if i == 0:
self.instrList[0].emit(stream, cnt)
stream.write('loop' + str(cnt) + ':\n')
else:
self.instrList[i].emit(stream, cnt)
stream.write('out' + str(cnt) + ':\n')
return cnt
#指令类
class Instruction:
def __init__(self):
self.rs = [] #源寄存器,是一个列表,其中的元素是该指令读取的所有寄存器号
#注意这个列表里去掉了重复的元素
self.rt = None #目的寄存器,是该指令写入的寄存器号
self.instrStr = None #指令字符串
def emit(self, stream, cnt):
pass
#存储访问指令类
class MemInstr(Instruction):
def emit(self, stream, cnt):
stream.write(self.instrStr + '\n')
return cnt
#Load
class Load(MemInstr):
#load reg1, offset(reg2)
def __init__(self, reg1, offset, reg2):
super().__init__()
self.rt = reg1
self.rs.append(reg2)
self.offset = offset
self.instrStr = 'load r' + str(reg1) + ', ' + str(offset) + '(r' + str(reg2) + ')'
#Store
class Store(MemInstr):
#store reg1, imm(reg2)
def __init__(self, reg1, offset, reg2):
super().__init__()
#去掉重复的元素
self.rs.append(reg1)
if reg1 != reg2:
self.rs.append(reg2)
self.offset = offset
self.instrStr = 'store r' + str(reg1) + ', ' + str(offset) + '(r' + str(reg2) + ')'
#ALU型指令类
class AluInstr(Instruction):
def emit(self, stream, cnt):
stream.write(self.instrStr + '\n')
return cnt
#Nop
class Nop(AluInstr):
#nop
def __init__(self):
super().__init__()
self.instrStr = 'nop'
#Add
class Add(AluInstr):
#add reg1, reg2, reg3
def __init__(self, reg1, reg2, reg3):
super().__init__()
self.rt = reg1
#去掉重复的元素
self.rs.append(reg2)
if reg2 != reg3:
self.rs.append(reg3)
self.instrStr = 'add r' + str(reg1) + ', r' + str(reg2) + ', ' + str(reg3)
#Move
class Move(AluInstr):
#move reg1, reg2
def __init__(self, reg1, reg2):
super().__init__()
self.rt = reg1
self.rs.append(reg2)
self.instrStr = 'move r' + str(reg1) + ', r' + str(reg2)
#Addi
class Addi(AluInstr):
#addi reg1, reg2, imm
def __init__(self, reg1, reg2, imm):
super().__init__()
self.rt = reg1
self.rs.append(reg2)
self.imm = imm
self.instrStr = 'addi r' + str(reg1) + ', r' + str(reg2) + ', ' + str(imm)
#条件跳转指令类
class Condition(Instruction):
pass
#Bne
class Bne(Condition):
#bne reg1, reg2, label
def __init__(self, reg1, reg2):
#Bne对象的属性中不需要包含label它应该在将中间表示转化为代码时被加上
super().__init__()
#去掉重复的元素
self.rs.append(reg1)
if reg1 != reg2:
self.rs.append(reg2)
self.instrStr = 'bne r' + str(reg1) + ', r' + str(reg2)
def emit(self, stream, cnt):
instrStr = self.instrStr + ', out' + str(cnt)
stream.write(instrStr + '\n')
return cnt
#Beq
class Beq(Condition):
#beq reg1, reg2, label
def __init__(self, reg1, reg2):
super().__init__()
#去掉重复的元素
self.rs.append(reg1)
if reg1 != reg2:
self.rs.append(reg2)
self.instrStr = 'beq r' + str(reg1) + ', r' + str(reg2)
def emit(self, stream, cnt):
instrStr = self.instrStr + ', loop' + str(cnt)
stream.write(instrStr + '\n')
return cnt