|
|
|
|
#程序类
|
|
|
|
|
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
|