Example #1
0
    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
Example #2
0
 def allocate_frame_size(self):
     return MOVE(TEMP(self.sp), BINOP('-', TEMP(self.sp),
                                      CONST(self.offset)))
Example #3
0
 def toSxp(self, fp):
     return MEM(BINOP('+', fp, CONST(self.offset)))
Example #4
0
 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 []