def load_spill(self, temp, offset): assert isinstance(temp, Temp) assert isinstance(offset, int) return [ O("ldr {{}}, [{{}}, #{:d}]".format(offset), dsts=[temp], srcs=[self.fp]) ]
def visit(self, mem): # Registre pour stocker le résultat temp = Temp.create("mem") # On évalue l'adresse du MEM adr_stms, adr_temp = mem.exp.accept(self) # On détermine les instructions à effectuer stms = adr_stms + [O("ldr {}, [{}]", dsts=[temp], srcs=[adr_temp])] # On retourne les instructions et le résultat return stms, temp
def visit(self, label): l = L("{}:".format(label.label), label.label) if label.label == self.frame.end_label: # The end label marks the place of the return instruction srcs = [self.frame.lr] if self.frame.returns_value: srcs.append(self.frame.r0) return [l, O("bx {}", srcs=srcs)] else: return [l]
def visit(self, move): src_stms, src_temp = move.src.accept(self) if isinstance(move.dst, MEM): # If we try to move into memory, use a store dst_stms, dst_temp = move.dst.exp.accept(self) return src_stms + dst_stms + [ O("str {1}, [{0}]", srcs=[src_temp, dst_temp]) ] else: # The only other possibility is a temporary, this is a move instruction return src_stms + [ M("mov {}, {}", dst=move.dst.temp, src=src_temp) ]
def visit(self, cjump): left_stms, left_temp = cjump.left.accept(self) right_stms, right_temp = cjump.right.accept(self) if cjump.op == "=": op = "beq" elif cjump.op == "<>": op = "bne" elif cjump.op == "<": op = "blt" elif cjump.op == "<=": op = "ble" elif cjump.op == ">": op = "bgt" elif cjump.op == ">=": op = "bge" else: raise AssertionError("unimplemented operator {}".format(cjump.op)) return left_stms + right_stms + [ O("cmp {}, {}", srcs=[left_temp, right_temp]), O("{} {}".format(op, cjump.ifTrue.label.name), jmps=[cjump.ifTrue.label, cjump.ifFalse.label]) ]
def visit(self, func): # Register used to stock result temp = Temp.create("func") # Saving registers stms = [O("push {{r0-r3,lr}}")] args_count = 0 for arg in func.args: (stm, tmp) = arg.accept(self) stms += stm if (args_count < 4): stms += [ M("mov {{}}, {{}}", dst=Temp("r{}".format(args_count)), src=tmp) ] else: stms += [O("push {{{}}}", srcs=[tmp])] args_count += 1 stms += [O("pop {{r0-r3,lr}}")] stms += [ O("bl {}".format(func.func.label.name), jmps=[func.func.label]) ] return stms, temp
def visit(self, binop): # Register used to stock result temp = Temp.create("binop") # Binop evaluation left_stms, left_temp = binop.left.accept(self) right_stms, right_temp = binop.right.accept(self) if binop.op == "+": op = "add" elif binop.op == "-": op = "sub" elif binop.op == "*": op = "mul" elif binop.op == "/": op = "sdiv" else: raise AssertionError("unimplemented operator {}".format(binop.op)) # Determination of instructions to do stms = left_stms + right_stms + [ O("{} {}, {}, {}".format(op, temp, left_temp, right_temp)) ] return stms, temp
def reserve_stack_space(self): return [O("add {{}}, {{}}, #-{}".format(self.offset), dsts=[self.sp], srcs=[self.sp])] \ if self.offset else []
def save_spill(self, temp, offset): assert isinstance(temp, Temp) assert isinstance(offset, int) return [ O("str {{}}, [{{}}, #{:d}]".format(offset), srcs=[temp, self.fp]) ]
def visit(self, jmp): return [ O("jmp {}".format(jmp.target.label.name), [], [], [jmp.target.label]) ]
def visit(self, const): temp = Temp.create("const") return [O("mov {{}}, #{}".format(const.value), dsts=[temp])], temp