def prologue(self): """Return the function prologue and some opaque value which will be passed to the epilogue. It can be used to pass a register map to be restored from the epilogue for example. In this generic method, we will pass around a list of move instructions needed to restore the callee-save registers and the frame pointer. It is expected that specific frames will generate more specialized prologues, using dedicated instructions such as push and pop that cannot be easily represented using the IR.""" begin_label = LABEL(self.label) # Push the previous frame pointer and the static link to the stack # and setup the new frame pointer. save_fp = [MOVE(TEMP(self.sp), BINOP("+", TEMP(self.sp), CONST(-self.word_size))), MOVE(MEM(TEMP(self.sp)), TEMP(self.fp)), MOVE(TEMP(self.sp), BINOP("+", TEMP(self.sp), CONST(-self.word_size))), MOVE(MEM(TEMP(self.sp)), TEMP(self.param_regs[0])), MOVE(TEMP(self.fp), TEMP(self.sp))] + \ self.allocate_frame_size() restore_fp = [ MOVE(TEMP(self.sp), BINOP("+", TEMP(self.fp), CONST(self.word_size))), MOVE(TEMP(self.fp), MEM(TEMP(self.sp))), MOVE(TEMP(self.sp), BINOP("+", TEMP(self.sp), CONST(self.word_size))) ] # Code to save and restore the callee-save registers. save_callee_save, restore_callee_save = self.preserve_callee_save() # Code to transfer the parameters from registers or call stack into the # register or the frame position they belong to (according to their # Access parameter). The first parameter (r0, in which the static link # had been written) has already been handled above. store_parameters = self.transfer_parameters() return [begin_label] + save_fp + save_callee_save + \ store_parameters, restore_callee_save + restore_fp
def allocate_frame_size(self): return MOVE(TEMP(self.sp), BINOP('-', TEMP(self.sp), CONST(self.offset)))
def toSxp(self, fp): return MEM(BINOP('+', fp, CONST(self.offset)))
def allocate_frame_size(self): """In IRVM, we know the frame size at this stage already since we have an infinite number of registers and thus no spills.""" return [MOVE(TEMP(self.sp), BINOP('+', TEMP(self.sp), CONST(-self.offset)))] \ if self.offset else []