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 TestLiterals(): import corepy.arch.ppc.platform as env prgm = env.Program() code = prgm.get_stream() prgm += code proc = env.Processor() ppc.set_active_code(code) vmx.set_active_code(code) zero = Bits.cast(SignedByte(0)) target = Bits() # Signed versions use splat, unsigned arrays b = Byte(2) sb = SignedByte(-2) vmx.vaddsbs(b, b, sb) h = Halfword(9999) sh = SignedHalfword(-9999) vmx.vaddshs(h, h, sh) w = Word(99999) sw = SignedWord(-99999) vmx.vaddsws(w, w, sw) # Combine the results (should be [0,0,0,0]) vmx.vor(target, b, h) vmx.vor(target, target, w) # Array initializers b = Byte(range(16)) sb = SignedByte(range(16)) vmx.vsubsbs(b, b, sb) vmx.vor(target, target, b) h = Halfword([9999,9998,9997,9996,9995,9994,9993,9992]) sh = SignedHalfword([9999,9998,9997,9996,9995,9994,9993,9992]) vmx.vsubshs(h, h, sh) vmx.vor(target, target, h) w = Word([99999,99998,99997,99996]) sw = SignedWord([99999,99998,99997,99996]) vmx.vsubsws(w, w, sw) target.v = vmx.vor.ex(target, w) result = extarray.extarray('I', [42,42,42,42]) r_addr = prgm.acquire_register() util.load_word(code, r_addr, result.buffer_info()[0]) vmx.stvx(target, 0, r_addr) ppc.set_active_code(None) vmx.set_active_code(None) r = proc.execute(prgm) print result for i in result: assert(i == 0) # for i in result: print '%08X' % i, # print return
def TestLiterals(): import corepy.arch.ppc.platform as env prgm = env.Program() code = prgm.get_stream() prgm += code proc = env.Processor() ppc.set_active_code(code) vmx.set_active_code(code) zero = Bits.cast(SignedByte(0)) target = Bits() # Signed versions use splat, unsigned arrays b = Byte(2) sb = SignedByte(-2) vmx.vaddsbs(b, b, sb) h = Halfword(9999) sh = SignedHalfword(-9999) vmx.vaddshs(h, h, sh) w = Word(99999) sw = SignedWord(-99999) vmx.vaddsws(w, w, sw) # Combine the results (should be [0,0,0,0]) vmx.vor(target, b, h) vmx.vor(target, target, w) # Array initializers b = Byte(range(16)) sb = SignedByte(range(16)) vmx.vsubsbs(b, b, sb) vmx.vor(target, target, b) h = Halfword([9999, 9998, 9997, 9996, 9995, 9994, 9993, 9992]) sh = SignedHalfword([9999, 9998, 9997, 9996, 9995, 9994, 9993, 9992]) vmx.vsubshs(h, h, sh) vmx.vor(target, target, h) w = Word([99999, 99998, 99997, 99996]) sw = SignedWord([99999, 99998, 99997, 99996]) vmx.vsubsws(w, w, sw) target.v = vmx.vor.ex(target, w) result = extarray.extarray('I', [42, 42, 42, 42]) r_addr = prgm.acquire_register() util.load_word(code, r_addr, result.buffer_info()[0]) vmx.stvx(target, 0, r_addr) ppc.set_active_code(None) vmx.set_active_code(None) r = proc.execute(prgm) print result for i in result: assert (i == 0) # for i in result: print '%08X' % i, # print return
code.reset() ppc.set_active_code(code) vmx.set_active_code(code) v_x = prgm.acquire_register('vector') result = array.array('I', [0,0,0,0,0,0]) r_addr = prgm.acquire_register() # Minor hack to align the address to a 16-byte boundary. # Note that enough space was allocated in the array to # ensure the save location is valid. # (we are working on a cleaner memory management interface # for CorePy that will fix these annoying alignment issues) addr = result.buffer_info()[0] if addr % 16 != 0: addr += 16 - (addr % 16) print 'aligning addr' load_word(code, r_addr, addr) vmx.vspltisw(v_x, 4) vmx.stvx(v_x, 0, r_addr) ppc.set_active_code(None) vmx.set_active_code(None) r = proc.execute(prgm) # , debug = True) # code.print_code(pro = True, epi = True) print result
code.reset() ppc.set_active_code(code) vmx.set_active_code(code) v_x = code.acquire_register('vector') result = array.array('I', [0, 0, 0, 0, 0, 0]) r_addr = code.acquire_register() # Minor hack to align the address to a 16-byte boundary. # Note that enough space was allocated in the array to # ensure the save location is valid. # (we are working on a cleaner memory management interface # for CorePy that will fix these annoying alignment issues) addr = result.buffer_info()[0] if addr % 16 != 0: addr += 16 - (addr % 16) print 'aligning addr' load_word(code, r_addr, addr) vmx.vspltisw(v_x, 4) vmx.stvx(v_x, 0, r_addr) ppc.set_active_code(None) vmx.set_active_code(None) r = proc.execute(code) # , debug = True) # code.print_code(pro = True, epi = True) print result
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
def store_current(self): return self.code.add(vmx.stvx(self.r_current, self.r_count, self.r_addr))