def _synthesize_epilogue(self): """ Save the values in some registers (see PPC ABI p41) """ # Reset the epilogue self._epilogue = [self.lbl_epilogue] # Restore vrsave self._epilogue.append(ppc.mtvrsave(self._vrsave)) # Get the list of saved registers 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 ] 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._epilogue, r_addr, self._saved_vx_registers.buffer_info()[0]) for i, reg in enumerate(save_vx): #print 'restoring vx:', reg, r_addr, i * WORD_SIZE * 4 self._load_word(self._epilogue, r_idx, i * WORD_SIZE * 4) self._epilogue.append( vmx.lvx(reg, r_idx, r_addr, ignore_active=True)) self._load_word(self._epilogue, r_addr, self._saved_fp_registers.buffer_info()[0]) for i, reg in enumerate(save_fp): # print 'restoring fp:', reg, r_addr, i * WORD_SIZE self._epilogue.append( ppc.lfd(reg, r_addr, i * WORD_SIZE * 2, ignore_active=True)) self._load_word(self._epilogue, r_addr, self._saved_gp_registers.buffer_info()[0]) for i, reg in enumerate(save_gp): # print 'restoring gp:', reg, r_addr, i * WORD_SIZE self._epilogue.append( ppc.lwz(reg, r_addr, i * WORD_SIZE, ignore_active=True)) self._epilogue.append(ppc.blr(ignore_active=True)) return
def _synthesize_epilogue(self): """ Save the values in some registers (see PPC ABI p41) """ # Reset the epilogue self._epilogue = [self.lbl_epilogue] r_addr = GPRegister(13) # Only available volatile register r_idx = GPRegister(14) # Non-volatile; safe to use before restoring # Get the list of saved registers save_gp = [r for r in self._used_registers[GPRegister] if r in gp_save] save_fp = [r for r in self._used_registers[FPRegister] if r in fp_save] if self._enable_vmx: save_vx = [ r for r in self._used_registers[VMXRegister] if r in vx_save ] if len(save_vx) > 0: # Restore vrsave self._epilogue.append( ppc.mtvrsave(self._vrsave, ignore_active=True)) # Restore saved VMX registers self._load_word(self._epilogue, r_addr, self._saved_vx_registers.buffer_info()[0]) for i, reg in enumerate(save_vx): self._load_word(self._epilogue, r_idx, i * WORD_SIZE * 4) self._epilogue.append( vmx.lvx(reg, r_idx, r_addr, ignore_active=True)) if len(save_fp) > 0: # Restore saved FP registers self._load_word(self._epilogue, r_addr, self._saved_fp_registers.buffer_info()[0]) for i, reg in enumerate(save_fp): self._epilogue.append( ppc.lfd(reg, r_addr, i * WORD_SIZE * 2, ignore_active=True)) if len(save_gp) > 0: # Restore saved GP registers self._load_word(self._epilogue, r_addr, self._saved_gp_registers.buffer_info()[0]) for i, reg in enumerate(save_gp): self._epilogue.append( ppc.lwz(reg, r_addr, i * WORD_SIZE, ignore_active=True)) self._epilogue.append(ppc.blr(ignore_active=True)) return
def _synthesize_epilogue(self): """ Save the values in some registers (see PPC ABI p41) """ # Reset the epilogue self._epilogue = [self.lbl_epilogue] r_addr = GPRegister(13) # Only available volatile register r_idx = GPRegister(14) # Non-volatile; safe to use before restoring # Get the list of saved registers save_gp = [r for r in self._used_registers[GPRegister] if r in gp_save] save_fp = [r for r in self._used_registers[FPRegister] if r in fp_save] if self._enable_vmx: save_vx = [r for r in self._used_registers[VMXRegister] if r in vx_save] if len(save_vx) > 0: # Restore vrsave self._epilogue.append(ppc.mtvrsave(self._vrsave, ignore_active = True)) # Restore saved VMX registers self._load_word(self._epilogue, r_addr, self._saved_vx_registers.buffer_info()[0]) for i, reg in enumerate(save_vx): self._load_word(self._epilogue, r_idx, i * WORD_SIZE * 4) self._epilogue.append( vmx.lvx(reg, r_idx, r_addr, ignore_active = True)) if len(save_fp) > 0: # Restore saved FP registers self._load_word(self._epilogue, r_addr, self._saved_fp_registers.buffer_info()[0]) for i, reg in enumerate(save_fp): self._epilogue.append( ppc.lfd(reg, r_addr, i * WORD_SIZE * 2, ignore_active = True)) if len(save_gp) > 0: # Restore saved GP registers self._load_word(self._epilogue, r_addr, self._saved_gp_registers.buffer_info()[0]) for i, reg in enumerate(save_gp): self._epilogue.append( ppc.lwz(reg, r_addr, i * WORD_SIZE, ignore_active = True)) self._epilogue.append(ppc.blr(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
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