def spill_slot(self): """ Returns an unused stack location. """ if self.free_stack_slots: return self.free_stack_slots.pop() else: self.spill_offset -= 4 return stack_slot(self.spill_offset)
def emit(self, allocator): in_size = self._stack_size(self.initial_spill_offset) our_size = self._stack_size(allocator.spill_offset) if in_size != our_size: assert our_size > in_size self.emit_stack_adjustment(our_size) if self.rgenop.DEBUG_SCRIBBLE: for offset in range(in_size, our_size, 4): self.asm.load_word(rSCRATCH, 0x23456789) self.asm.stw(rSCRATCH, rSP, -offset) if self.rgenop.DEBUG_SCRIBBLE: locs = {} for _, loc in self.initial_var2loc.iteritems(): locs[loc] = True regs = insn.gprs[3:] for reg in regs: if reg not in locs: self.asm.load_word(reg.number, 0x3456789) self.asm.load_word(0, 0x3456789) for offset in range(self._var_offset(0), self.initial_spill_offset, -4): if insn.stack_slot(offset) not in locs: self.asm.stw(0, rFP, offset) for insn_ in self.insns: insn_.emit(self.asm) for label in allocator.labels_to_tell_spill_offset_to: label.min_stack_offset = allocator.spill_offset for builder in allocator.builders_to_tell_spill_offset_to: builder.initial_spill_offset = allocator.spill_offset return allocator
def _write_prologue(self, sigtoken): numargs = sigtoken # for now if DEBUG_TRAP: self.asm.trap() inputargs = [Var() for i in range(numargs)] assert self.initial_var2loc is None self.initial_var2loc = {} for arg in inputargs[:8]: self.initial_var2loc[arg] = gprs[3 + len(self.initial_var2loc)] if len(inputargs) > 8: for i in range(8, len(inputargs)): arg = inputargs[i] self.initial_var2loc[arg] = insn.stack_slot( 24 + 4 * len(self.initial_var2loc)) self.initial_spill_offset = self._var_offset(0) # Standard prologue: # Minimum stack space = 24+params+lv+4*GPRSAVE+8*FPRSAVE # params = stack space for parameters for functions we call # lv = stack space for local variables # GPRSAVE = the number of callee-save GPRs we save, currently # NSAVEDREGISTERS which is 19, i.e. all of them # FPRSAVE = the number of callee-save FPRs we save, currently 0 # Initially, we set params == lv == 0 and allow each basic block to # ensure it has enough space to continue. minspace = self._stack_size(self._var_offset(0)) # save Link Register self.asm.mflr(rSCRATCH) self.asm.stw(rSCRATCH, rSP, 8) # save Condition Register self.asm.mfcr(rSCRATCH) self.asm.stw(rSCRATCH, rSP, 4) # save the callee-save GPRs self.asm.stmw(gprs[32 - NSAVEDREGISTERS].number, rSP, -4 * (NSAVEDREGISTERS + 1)) # set up frame pointer self.asm.mr(rFP, rSP) # save stack pointer into linkage area and set stack pointer for us. self.asm.stwu(rSP, rSP, -minspace) if self.rgenop.DEBUG_SCRIBBLE: # write junk into all non-argument, non rFP or rSP registers self.asm.load_word(rSCRATCH, 0x12345678) for i in range(min(11, 3 + len(self.initial_var2loc)), 32): self.asm.load_word(i, 0x12345678) # scribble the part of the stack between # self._var_offset(0) and minspace for offset in range(self._var_offset(0), -minspace, -4): self.asm.stw(rSCRATCH, rFP, offset) # and then a bit more for offset in range(-minspace - 4, -minspace - 200, -4): self.asm.stw(rSCRATCH, rFP, offset) return inputargs
def _write_prologue(self, sigtoken): numargs = sigtoken # for now if DEBUG_TRAP: self.asm.trap() inputargs = [Var() for i in range(numargs)] assert self.initial_var2loc is None self.initial_var2loc = {} for arg in inputargs[:8]: self.initial_var2loc[arg] = gprs[3+len(self.initial_var2loc)] if len(inputargs) > 8: for i in range(8, len(inputargs)): arg = inputargs[i] self.initial_var2loc[arg] = insn.stack_slot(24 + 4 * len(self.initial_var2loc)) self.initial_spill_offset = self._var_offset(0) # Standard prologue: # Minimum stack space = 24+params+lv+4*GPRSAVE+8*FPRSAVE # params = stack space for parameters for functions we call # lv = stack space for local variables # GPRSAVE = the number of callee-save GPRs we save, currently # NSAVEDREGISTERS which is 19, i.e. all of them # FPRSAVE = the number of callee-save FPRs we save, currently 0 # Initially, we set params == lv == 0 and allow each basic block to # ensure it has enough space to continue. minspace = self._stack_size(self._var_offset(0)) # save Link Register self.asm.mflr(rSCRATCH) self.asm.stw(rSCRATCH, rSP, 8) # save Condition Register self.asm.mfcr(rSCRATCH) self.asm.stw(rSCRATCH, rSP, 4) # save the callee-save GPRs self.asm.stmw(gprs[32-NSAVEDREGISTERS].number, rSP, -4*(NSAVEDREGISTERS + 1)) # set up frame pointer self.asm.mr(rFP, rSP) # save stack pointer into linkage area and set stack pointer for us. self.asm.stwu(rSP, rSP, -minspace) if self.rgenop.DEBUG_SCRIBBLE: # write junk into all non-argument, non rFP or rSP registers self.asm.load_word(rSCRATCH, 0x12345678) for i in range(min(11, 3+len(self.initial_var2loc)), 32): self.asm.load_word(i, 0x12345678) # scribble the part of the stack between # self._var_offset(0) and minspace for offset in range(self._var_offset(0), -minspace, -4): self.asm.stw(rSCRATCH, rFP, offset) # and then a bit more for offset in range(-minspace-4, -minspace-200, -4): self.asm.stw(rSCRATCH, rFP, offset) return inputargs