def store(self, addr, offset = 0): # If addr is a constant, create a variable and store the value if not issubclass(type(addr), spe.Type): r_storage = self.code.prgm.acquire_register() addr = Bits(addr, reg = r_storage) else: r_storage = None # If offset is a constant, use lfd, otherwise use lfdx if issubclass(type(offset), spe.Type): self.code.add(ppc.stfdx(self, addr, offset)) else: # TODO: Check size of offset to ensure it fits in the immediate field self.code.add(ppc.stfd(self, addr, offset)) if r_storage is not None: self.code.prgm.release_register(r_storage) return
def _synthesize_prologue(self): """ Create the prologue. (see PPC ABI p41) This manages the register preservation requirements from the ABI. TODO: CR2-4 need to be preserved. """ # Reset the prologue self._prologue = [self.lbl_prologue] # Add the instructions to save the registers r_addr = GPRegister(13) # Only available volatile register r_idx = GPRegister(14) # Non-volatile; safe to use before restoring # TODO - AWF - don't want to push things on the stack, that changes the # relative location of the passed-in arguments # However, we could just use the stack to save all the registers, and use # a frame pointer to give access to the arguments save_gp = [r for r in self._used_registers[GPRegister] if r in gp_save] if len(save_gp) > 0: # Save GP registers self._saved_gp_registers = array.array("I", xrange(len(save_gp))) self._load_word(self._prologue, r_addr, self._saved_gp_registers.buffer_info()[0]) for i, reg in enumerate(save_gp): self._prologue.append(ppc.stw(reg, r_addr, i * WORD_SIZE, ignore_active=True)) save_fp = [r for r in self._used_registers[FPRegister] if r in fp_save] if len(save_fp) > 0: # Save FP registers self._saved_fp_registers = array.array("d", xrange(len(save_fp))) self._load_word(self._prologue, r_addr, self._saved_fp_registers.buffer_info()[0]) for i, reg in enumerate(save_fp): self._prologue.append(ppc.stfd(reg, r_addr, i * WORD_SIZE * 2, ignore_active=True)) if self._enable_vmx: save_vx = [r for r in self._used_registers[VMXRegister] if r in vx_save] if len(save_vx) > 0: # Save VMX registers self._saved_vx_registers = extarray.extarray("I", range(len(save_vx) * 4)) self._load_word(self._prologue, r_addr, self._saved_vx_registers.buffer_info()[0]) for i, reg in enumerate(save_vx): self._load_word(self._prologue, r_idx, i * WORD_SIZE * 4) self._prologue.append(vmx.stvx(reg, r_idx, r_addr, ignore_active=True)) # Set up VRSAVE # Currently, we save the old value of VRSAVE in r31. # On the G4, someone stomps on registers < 20 ... save them all for now. # Save vrsave and put our value in it self._prologue.append(ppc.mfvrsave(self._vrsave, ignore_active=True)) self._load_word(self._prologue, r_addr, 0xFFFFFFFF) self._prologue.append(ppc.mtvrsave(r_addr, ignore_active=True)) return
def _synthesize_prologue(self): """ Create the prologue. (see PPC ABI p41) This manages the register preservation requirements from the ABI. TODO: CR2-4 need to be preserved. """ # Reset the prologue self._prologue = [self.lbl_prologue] # Get the lists of registers to save save_gp = [ reg for reg in self._register_files[GPRegister].get_used() if reg in gp_save ] save_fp = [ reg for reg in self._register_files[FPRegister].get_used() if reg in fp_save ] save_vx = [ reg for reg in self._register_files[VMXRegister].get_used() if reg in vx_save ] self._saved_gp_registers = array.array('I', range(len(save_gp))) self._saved_fp_registers = array.array('d', range(len(save_fp))) self._saved_vx_registers = array.array('I', range(len(save_vx) * 4)) # Add the instructions to save the registers # Store the value in register 2 in the red zone # r1 is the stackpointer, -4(r1) is in the red zone r_addr = GPRegister(13, None) # Only available volatile register r_idx = GPRegister(14, None) # Non-volatile; safe to use before restoring self._load_word(self._prologue, r_addr, self._saved_gp_registers.buffer_info()[0]) for i, reg in enumerate(save_gp): # print 'saving gp:', reg, 2, i * WORD_SIZE self._prologue.append( ppc.stw(reg, r_addr, i * WORD_SIZE, ignore_active=True)) self._load_word(self._prologue, r_addr, self._saved_fp_registers.buffer_info()[0]) for i, reg in enumerate(save_fp): # print 'saving fp:', reg, 2, i * WORD_SIZE self._prologue.append( ppc.stfd(reg, r_addr, i * WORD_SIZE * 2, ignore_active=True)) self._load_word(self._prologue, r_addr, self._saved_vx_registers.buffer_info()[0]) for i, reg in enumerate(save_vx): #print 'saving vx:', reg, 2, i * WORD_SIZE self._load_word(self._prologue, r_idx, i * WORD_SIZE * 4) self._prologue.append( vmx.stvx(reg, r_idx, r_addr, ignore_active=True)) # print 'TODO: VMX Support' # Set up VRSAVE # Currently, we save the old value of VRSAVE in r31. # On the G4, someone stomps on registers < 20 ... save them all for now. # Save vrsave and put our value in it self._prologue.append(ppc.mfvrsave(self._vrsave, ignore_active=True)) self._load_word(self._prologue, r_addr, 0xFFFFFFFF) self._prologue.append(ppc.mtvrsave(r_addr, ignore_active=True)) return
def _synthesize_prologue(self): """ Create the prologue. (see PPC ABI p41) This manages the register preservation requirements from the ABI. TODO: CR2-4 need to be preserved. """ # Reset the prologue self._prologue = [self.lbl_prologue] # Add the instructions to save the registers r_addr = GPRegister(13) # Only available volatile register r_idx = GPRegister(14) # Non-volatile; safe to use before restoring # TODO - AWF - don't want to push things on the stack, that changes the # relative location of the passed-in arguments # However, we could just use the stack to save all the registers, and use # a frame pointer to give access to the arguments save_gp = [r for r in self._used_registers[GPRegister] if r in gp_save] if len(save_gp) > 0: # Save GP registers self._saved_gp_registers = array.array('I', xrange(len(save_gp))) self._load_word(self._prologue, r_addr, self._saved_gp_registers.buffer_info()[0]) for i, reg in enumerate(save_gp): self._prologue.append( ppc.stw(reg, r_addr, i * WORD_SIZE, ignore_active=True)) save_fp = [r for r in self._used_registers[FPRegister] if r in fp_save] if len(save_fp) > 0: # Save FP registers self._saved_fp_registers = array.array('d', xrange(len(save_fp))) self._load_word(self._prologue, r_addr, self._saved_fp_registers.buffer_info()[0]) for i, reg in enumerate(save_fp): self._prologue.append( ppc.stfd(reg, r_addr, i * WORD_SIZE * 2, ignore_active=True)) if self._enable_vmx: save_vx = [ r for r in self._used_registers[VMXRegister] if r in vx_save ] if len(save_vx) > 0: # Save VMX registers self._saved_vx_registers = extarray.extarray( 'I', range(len(save_vx) * 4)) self._load_word(self._prologue, r_addr, self._saved_vx_registers.buffer_info()[0]) for i, reg in enumerate(save_vx): self._load_word(self._prologue, r_idx, i * WORD_SIZE * 4) self._prologue.append( vmx.stvx(reg, r_idx, r_addr, ignore_active=True)) # Set up VRSAVE # Currently, we save the old value of VRSAVE in r31. # On the G4, someone stomps on registers < 20 ... save them all for now. # Save vrsave and put our value in it self._prologue.append( ppc.mfvrsave(self._vrsave, ignore_active=True)) self._load_word(self._prologue, r_addr, 0xFFFFFFFF) self._prologue.append(ppc.mtvrsave(r_addr, ignore_active=True)) return