def __init__(self, symtable, threeAC): self.symtable = symtable self.code = threeAC.code self.unused_register = unused_register_list.copy() # 基本块 self.basic_blocks = [] # 接下来使用 self.next_use = [] # 每个基本块对应一个label名 self.block_label = {} # {(startline, endline): label_name} # symbol 被存在哪些寄存器里 self.symbol_register = {}
def handle_return(self, codeline): line_num, _, lhs, _, _ = codeline print("[This line]: ", codeline) # 寄存器存回内存 for op in self.symbol_register: reg = self.symbol_register[op] self.asmcode.append(self.store_mem(op, reg, self.scopeStack)) self.symbol_register.clear() self.allocReg.unused_register = unused_register_list.copy() topDeleted = self.scopeStack.pop().lower() # TODO 恢复参数 (引用传递 # : 将返回值放到v0 if lhs == None: pass else: self.asmcode.append( 'lw $v0, -%d($fp)' % self.symtable[topDeleted].get("_return").offset) # 指针 self.asmcode.append('addi $sp, $sp, %d' % (self.symtable[topDeleted].width + 76)) self.asmcode.append('lw $fp, 72($fp)') # 恢复寄存器 for index in range(8, 24): # SW R1, 0(R2) # FIXME: self.asmcode.append("lw $%s, %d($sp)" % (index, -12 - (index - 8) * 4)) # 恢复返回地址 ra self.asmcode.append('move $t8, $ra') # ra' self.asmcode.append('lw $ra, -8($sp)') # FIXME: 需要填好返回值,然后放回ra,最后返还stack上分配的内存,返回 self.asmcode.append('jr $t8') # 这个地方不是跳转到ra,因为ra已经恢复成跳转之后的返回地址了
def tacToasm(self): for i in range(len(self.allocReg.basic_blocks)): start, end = self.allocReg.basic_blocks[i] block_code = self.code[start:end + 1] for codeline in block_code: self.asmcode.append('\n# %s' % ' '.join(str(code) for code in codeline)) line_num, operation, lhs, op1, op2 = codeline if hasattr(lhs, 'reference') and lhs.reference or \ hasattr(op1, 'reference') and op1.reference or \ hasattr(op2, 'reference') and op2.reference: for op in self.symbol_register: reg = self.symbol_register[op] self.asmcode.append( self.store_mem(op, reg, self.scopeStack)) self.symbol_register.clear() self.allocReg.unused_register = unused_register_list.copy() if operation in binary_list: self.handle_binary(codeline) elif operation in ['>', '<', '>=', '<=', '=']: self.handle_cmp(codeline) elif operation in ['BNE', 'BEQ', 'JMP']: if codeline == block_code[-1]: for op in self.symbol_register: reg = self.symbol_register[op] self.asmcode.append( self.store_mem(op, reg, self.scopeStack)) self.handle_jmp(codeline) self.symbol_register.clear() self.allocReg.unused_register = unused_register_list.copy( ) else: self.handle_jmp(codeline) elif operation == 'LABEL': self.handle_label(codeline) elif operation == 'CALL': self.handle_call(codeline) elif operation == 'PARAM': self.handle_params(codeline) elif operation == 'REFER': self.handle_refers(codeline) elif operation == 'RETURN': self.handle_return(codeline) elif operation == 'INPUT': self.handle_input(codeline) elif operation in ['PRINT', 'PRINTLN']: self.handle_print(codeline) elif operation == 'LOADREF': self.handle_loadref(codeline) elif operation == 'STOREREF': self.handle_storeref(codeline) if hasattr(lhs, 'reference') and lhs.reference or \ hasattr(op1, 'reference') and op1.reference or \ hasattr(op2, 'reference') and op2.reference: for op in self.symbol_register: reg = self.symbol_register[op] self.asmcode.append( self.store_mem(op, reg, self.scopeStack)) self.symbol_register.clear() self.allocReg.unused_register = unused_register_list.copy() if block_code[-1][1] not in ['JMP', 'BNE', 'BEQ']: for op in self.symbol_register: reg = self.symbol_register[op] self.asmcode.append( self.store_mem(op, reg, self.scopeStack)) self.symbol_register.clear() self.allocReg.unused_register = unused_register_list.copy()
def handle_call(self, codeline): print("[This line]: ", codeline) for op in self.symbol_register.keys(): reg = self.symbol_register[op] self.asmcode.append(self.store_mem(op, reg, self.scopeStack)) self.symbol_register.clear() self.allocReg.unused_register = unused_register_list.copy() self.paraCounter = 0 # TODO: 访问链:判断两个scope之间的关系 self.scopeStack[-1] print("****") print(codeline[4]) print(self.scopeStack[-1]) print('.'.join(self.scopeStack[-1].split('.')[:-1])) # if codeline[4] == self.scopeStack[-1]: # # 访问控制 = fp # pass if codeline[4] == '.'.join(self.scopeStack[-1].split('.')[:-1]): # 访问控制 = 当前活动访问控制 # sp - 4 = self.asmcode.append("# = parent's") self.asmcode.append('lw $t8, 76($fp)') self.asmcode.append('sw $t8, 0($sp)') else: self.asmcode.append('# = fp') self.asmcode.append('sw $fp, 0($sp)') # 访问控制 = fp # 控制链 self.asmcode.append('sw $fp, -4($sp)') # ra self.asmcode.append('sw $ra, -8($sp)') # sw $ra -8($sp) # reg for index in range(8, 24): # SW R1, 0(R2) # FIXME: self.asmcode.append("sw $%s, %d($sp)" % (index, -12 - (index - 8) * 4)) # param 参数中处理 # self.asmcode.append('addi $fp $sp -76') scope_width = self.symtable['%s.%s' % (codeline[4], codeline[3].lower())].width self.asmcode.append('addi $sp $sp %d' % -(scope_width + 76)) # jal # self.asmcode.append("jal %s"%self.symtable[codeline[3]]) self.asmcode.append("jal %s" % codeline[3]) # 将返回值从 $v0 中取出 if codeline[2]: block_index = self.allocReg.line_block(codeline[0]) reg_lhs = self.handle_term(codeline[2], block_index, codeline[0]) self.asmcode.append("move, {}, $v0".format(reg_lhs))