def generate_str_cmp(self): self.current_procedure = mips.ProcedureNode(STR_CMP) #comparing char by char self.register_instruction(mips.CommentNode, "Comparing char by char") self.register_instruction(mips.LoadWordNode, s0, CHARS_ATTR_OFFSET, t6) #char array pointer offset self.register_instruction(mips.LoadWordNode, s1, CHARS_ATTR_OFFSET, t7) #char by char loop self.register_instruction(mips.Label, "strcmp_loop") self.register_instruction(mips.LoadInmediate, s2, 0) self.register_instruction(mips.LoadByteNode, s2, 0, s0) self.register_instruction(mips.LoadInmediate, s3, 0) self.register_instruction(mips.LoadByteNode, s3, 0, s1) self.register_instruction(mips.SetEq, a0, s2, s3) self.register_instruction(mips.BranchOnEqZero, a0, "end_loop") self.register_instruction(mips.BranchOnEqZero, s3, "end_loop") self.register_instruction(mips.BranchOnEqZero, s2, "end_loop") self.register_instruction(mips.AddiNode, s0, s0, 1) self.register_instruction(mips.AddiNode, s1, s1, 1) self.register_instruction(mips.Jump, "strcmp_loop") self.register_instruction(mips.Label, "end_loop") self.register_instruction(mips.JumpRegister, ra) self.text.append(self.current_procedure)
def generate_input(self): # copies from t7 to t6 a0 bytes self.memo.save() reg4 = self.memo.get_unused_reg() reg5 = self.memo.get_unused_reg() self.current_procedure = mips.ProcedureNode("Input") self.register_instruction(mips.Label, "input_loop") self.register_instruction(mips.LoadByteNode, t8, 0, t7) self.register_instruction(mips.StoreByteNode, t8, 0, t6) self.register_instruction(mips.AddiNode, t6, t6, 1) self.register_instruction(mips.AddiNode, t7, t7, 1) self.register_instruction(mips.BranchOnGreaterZero, t8, "input_loop") self.register_instruction(mips.AddiNode, t6, t6, -2) self.register_instruction(mips.LoadInmediate, reg4, 10) self.register_instruction(mips.LoadByteNode, reg5, 0, t6) self.register_instruction(mips.BranchOnNotEqualNode, reg4, reg5, "input_end") self.register_instruction(mips.LoadInmediate, t8, 0) self.register_instruction(mips.StoreByteNode, t8, 0, t6) self.register_instruction(mips.Label, "input_end") self.register_instruction(mips.Jump, ra) self.text.append(self.current_procedure)
def generate_str_length(self): # calculates the length of the null-terminated char array referenced by $a0 and stores it in $a0 self.memo.save() reg1 = self.memo.get_unused_reg() reg2 = self.memo.get_unused_reg() self.current_procedure = mips.ProcedureNode(LENGTH) self.register_instruction(mips.LoadInmediate, reg1, 0) self.register_instruction(mips.Label, "length_loop") self.register_instruction(mips.LoadByteNode, reg2, 0, a0) self.register_instruction(mips.BranchOnEqualNode, zero, reg2, "length_end") self.register_instruction(mips.AddiNode, reg1, reg1, 1) self.register_instruction(mips.AddiNode, a0, a0, 1) self.register_instruction(mips.Jump, "length_loop") self.register_instruction(mips.Label, "length_end") self.register_instruction(mips.MoveNode, a0, reg1) self.register_instruction(mips.Jump, ra) self.text.append(self.current_procedure) self.memo.clean()
def generate_copy(self): # copies from t1 to t6 a0 bytes self.memo.save() self.current_procedure = mips.ProcedureNode(COPY) self.register_instruction(mips.Label, "copy_loop") self.register_instruction(mips.BranchOnEqualNode, zero, a0, "copy_end") self.register_instruction(mips.LoadByteNode, t8, 0, t7) self.register_instruction(mips.StoreByteNode, t8, 0, t6) self.register_instruction(mips.AddiNode, t6, t6, 1) self.register_instruction(mips.AddiNode, t7, t7, 1) self.register_instruction(mips.AddiNode, a0, a0, -1) self.register_instruction(mips.Jump, "copy_loop") self.register_instruction(mips.Label, "copy_end") self.register_instruction(mips.Jump, ra) self.text.append(self.current_procedure) self.memo.clean()
def visit(self, node): self.memo.save() locals_save = self.locals params_save = self.params self.locals, self.params = [], [] self.current_procedure = mips.ProcedureNode(node.name) saved_fp = self.memo.get_unused_reg() self.register_instruction(mips.MoveNode, saved_fp, fp) self.register_instruction(mips.CommentNode, "New $fp") self.register_instruction(mips.MoveNode, fp, sp) self.register_instruction(mips.CommentNode, "Reserving space for locals") self.register_instruction(mips.AddiNode, sp, sp, 4 * len(node.localvars)) self.register_instruction(mips.CommentNode, "Pushing $ra") self.register_push(ra) self.register_instruction(mips.CommentNode, "Saving $fp") self.register_push(saved_fp) self.memo.clean() for local in node.localvars: self.locals.append(local.name) for param in node.params: self.params.append(param.name) self.register_instruction(mips.CommentNode, "Executing instructions") for inst in node.instructions: self.visit(inst) self.text.append(self.current_procedure) self.locals = locals_save self.params = params_save