def block(self): code = spu.get_active_code() self._block_idx = len(code) # --> add the branch instruction (use brz (?) to always branch, nop to never branch) code[self._branch_idx] = spu.nop(0, ignore_active=True) # code[self._branch_idx] = spu.brnz(self._cmp, self._block_idx - self._branch_idx, ignore_active = True) # code[self._branch_idx] = spu.brz(self._cmp, self._block_idx - self._branch_idx, ignore_active = True) # Pack result into vector # [x][y][score][--] # Zero the save value spu.xor(self._save_value, self._save_value, self._save_value) # Copy the score spu.selb(self._save_value, self._save_value, self._score, self._word_mask) spu.rotqbyi(self._save_value, self._save_value, 12) # Copy the y value spu.selb(self._save_value, self._save_value, self._y_off, self._word_mask) spu.rotqbyi(self._save_value, self._save_value, 12) # Copy the x value spu.selb(self._save_value, self._save_value, self._x_off, self._word_mask) # Save value to local store spu.stqx(self._save_value, self._count, self._md_results.r_addr) self._count.v = self._count.v + 16 # --> MemorySave test cmp = self._save_value # reuse the save register spu.ceq.ex(cmp, self._count, self._md_results.r_size) if self._save_op is not None: self._save_op.test(cmp, self._count) # Just reset for now spu.selb(self._count, self._count, 0, cmp) # Return to the loop idx = len(code) spu.br(-(idx - self._branch_idx - 1)) return
def block(self): code = spu.get_active_code() self._block_idx = len(code) # --> add the branch instruction code[self._branch_idx] = spu.nop(0, ignore_active = True) code[self._branch_idx] = spu.brnz(self._cmp, self._block_idx - self._branch_idx, ignore_active = True) # FILL IN HERE # Return to the loop idx = len(code) spu.br(- (idx - self._branch_idx - 1)) return
def block(self): code = spu.get_active_code() self._block_idx = len(code) # --> add the branch instruction (use brz (?) to always branch, nop to never branch) code[self._branch_idx] = spu.nop(0, ignore_active = True) # code[self._branch_idx] = spu.brnz(self._cmp, self._block_idx - self._branch_idx, ignore_active = True) # code[self._branch_idx] = spu.brz(self._cmp, self._block_idx - self._branch_idx, ignore_active = True) # Pack result into vector # [x][y][score][--] # Zero the save value spu.xor(self._save_value, self._save_value, self._save_value) # Copy the score spu.selb(self._save_value, self._save_value, self._score, self._word_mask) spu.rotqbyi(self._save_value, self._save_value, 12) # Copy the y value spu.selb(self._save_value, self._save_value, self._y_off, self._word_mask) spu.rotqbyi(self._save_value, self._save_value, 12) # Copy the x value spu.selb(self._save_value, self._save_value, self._x_off, self._word_mask) # Save value to local store spu.stqx(self._save_value, self._count, self._md_results.r_addr) self._count.v = self._count.v + 16 # --> MemorySave test cmp = self._save_value # reuse the save register spu.ceq.ex(cmp, self._count, self._md_results.r_size) if self._save_op is not None: self._save_op.test(cmp, self._count) # Just reset for now spu.selb(self._count, self._count, 0, cmp) # Return to the loop idx = len(code) spu.br(- (idx - self._branch_idx - 1)) return
def nexti(self): if len(self.last_stop) == 1: # Restore a single instruction current_inst = self.restore(self.last_stop[0]) last_idx = self.last_stop[0] else: # Restore two branch targets and determine which branch was taken # based on the stop code i1 = self.restore(self.last_stop[0]) i2 = self.restore(self.last_stop[1]) if self.stop_code == DEBUG_STOP: current_inst = i1 last_idx = self.last_stop[0] else: current_inst = i2 last_idx = self.last_stop[1] # If the current instruction is a branch, get the location # of all possible next instructions if isinstance(current_inst, (spu.br, spu.brsl)): next_stop = (self.last_stop[0] + current_inst.I16,) print 'next br:', next_stop elif isinstance(current_inst, (spu.bra, spu.brasl)): next_stop = (current_inst.I16 - (self.lsa >> 2),) elif isinstance(current_inst, (spu.brnz, spu.brz, spu.brhnz, spu.brhz)): next_stop = (self.last_stop[0] + 1, self.last_stop[0] + current_inst.I16) elif isinstance(current_inst, (spu.bi, spu.bisled, spu.bisl)): raise Exception("DebugProcessor does not support branch indirect (bi) instructions") else: next_stop = (self.last_stop[0] + 1,) # TODO: Get rid of last instruction. Do something smarter. last_instruction = (next_stop[0] == (self.debug_idx - 1)) # !!! STOPPED HERE !!! # !!! STILL WRONG !!! if not last_instruction: # Normal instructions and single target branches self.replace(next_stop[0], spu.bra(self.debug_lsa, ignore_active = True)) print 'target (1):', -(self.debug_lsa - ((self.lsa >> 2) + next_stop[0])), self.debug_lsa, last_idx, self.lsa self.replace(self.debug_branch, spu.br(-(self.debug_lsa - ((self.lsa >> 2) + next_stop[0])), ignore_active = True)) # Branch target for test-based branch instructions if len(next_stop) == 2: self.replace(next_stop[1], spu.bra(self.debug_target_lsa, ignore_active = True)) print 'target (2):', -(self.debug_target_lsa - ((self.lsa >> 2) + next_stop[1])), self.debug_target_lsa self.replace(self.debug_target_branch, spu.br(-(self.debug_target_lsa - ((self.lsa >> 2) + next_stop[1])), ignore_active = True)) # self.replace(next_stop, self.debug_stop) self.get_instructions() self.code.print_code() self.resume(self.spe_id) if last_instruction: r = self.join(self.spe_id) r = None else: r = self.wait_debug() self.last_stop = next_stop self.stop_code = r return r
def SimpleSPU(): """ A very simple SPU that computes 11 + 31 and returns 0xA on success. """ code = InstructionStream() proc = Processor() spu.set_active_code(code) # Acquire two registers #x = code.acquire_register() x = code.gp_return test = code.acquire_register() lbl_brz = code.get_label("BRZ") lbl_skip = code.get_label("SKIP") spu.hbrr(lbl_brz, lbl_skip) spu.xor(x, x, x) # zero x spu.ai(x, x, 11) # x = x + 11 spu.ai(x, x, 31) # x = x + 31 spu.ceqi(test, x, 42) # test = (x == 42) # If test is false (all 0s), skip the stop(0x100A) instruction code.add(lbl_brz) spu.brz(test, lbl_skip) spu.stop(0x100A) code.add(lbl_skip) spu.stop(0x100B) code.print_code(hex=True, pro=True, epi=True) r = proc.execute(code, mode='int', stop=True) print "ret", r assert (r[0] == 42) assert (r[1] == 0x100A) code = InstructionStream() spu.set_active_code(code) lbl_loop = code.get_label("LOOP") lbl_break = code.get_label("BREAK") r_cnt = code.acquire_register() r_stop = code.acquire_register() r_cmp = code.acquire_register() r_foo = code.gp_return spu.ori(r_foo, code.r_zero, 0) spu.ori(r_cnt, code.r_zero, 0) util.load_word(code, r_stop, 10) code.add(lbl_loop) spu.ceq(r_cmp, r_cnt, r_stop) spu.brnz(r_cmp, lbl_break) spu.ai(r_cnt, r_cnt, 1) spu.a(r_foo, r_foo, r_cnt) spu.br(lbl_loop) code.add(lbl_break) code.print_code() r = proc.execute(code, mode='int', stop=True) print "ret", r assert (r[0] == 55) return
def SimpleSPU(): """ A very simple SPU that computes 11 + 31 and returns 0xA on success. """ prgm = env.Program() code = prgm.get_stream() proc = env.Processor() spu.set_active_code(code) # Acquire two registers #x = code.acquire_register() x = prgm.gp_return test = prgm.acquire_register() lbl_brz = prgm.get_label("BRZ") lbl_skip = prgm.get_label("SKIP") spu.hbrr(lbl_brz, lbl_skip) spu.xor(x, x, x) # zero x spu.ai(x, x, 11) # x = x + 11 spu.ai(x, x, 31) # x = x + 31 spu.ceqi(test, x, 42) # test = (x == 42) # If test is false (all 0s), skip the stop(0x100A) instruction code.add(lbl_brz) spu.brz(test, lbl_skip) spu.stop(0x100A) code.add(lbl_skip) spu.stop(0x100B) prgm.add(code) prgm.print_code() r = proc.execute(prgm, mode = 'int', stop = True) print "ret", r assert(r[0] == 42) assert(r[1] == 0x100A) prgm = env.Program() code = prgm.get_stream() spu.set_active_code(code) lbl_loop = prgm.get_label("LOOP") lbl_break = prgm.get_label("BREAK") r_cnt = prgm.acquire_register() r_stop = prgm.acquire_register() r_cmp = prgm.acquire_register() r_foo = prgm.gp_return spu.ori(r_foo, prgm.r_zero, 0) spu.ori(r_cnt, prgm.r_zero, 0) util.load_word(code, r_stop, 10) code.add(lbl_loop) spu.ceq(r_cmp, r_cnt, r_stop) spu.brnz(r_cmp, lbl_break) spu.ai(r_cnt, r_cnt, 1) spu.a(r_foo, r_foo, r_cnt) spu.br(lbl_loop) code.add(lbl_break) prgm.add(code) prgm.print_code() r = proc.execute(prgm, mode = 'int', stop = True) print "ret", r assert(r[0] == 55) return
prgm = env.Program() code = prgm.get_stream() reg = prgm.acquire_register() foo = prgm.acquire_register(reg_name=5) code.add(prgm.get_label("FOO")) code.add(spu.il(foo, 0xCAFE)) code.add(spu.ilhu(reg, 0xDEAD)) code.add(spu.iohl(reg, 0xBEEF)) code.add(spu.stqd(reg, code.r_zero, 4)) lbl_loop = prgm.get_label("LOOP") lbl_break = prgm.get_label("BREAK") r_cnt = code.gp_return r_stop = prgm.acquire_register(reg_name=9) r_cmp = prgm.acquire_register() code.add(spu.ori(r_cnt, code.r_zero, 0)) code.add(spu.il(r_stop, 5)) code.add(lbl_loop) code.add(spu.ceq(r_cmp, r_cnt, r_stop)) code.add(spu.brnz(r_cmp, prgm.get_label("BREAK"))) code.add(spu.ai(r_cnt, r_cnt, 1)) code.add(spu.br(prgm.get_label("LOOP"))) code.add(lbl_break) app = SPUApp(code) app.MainLoop()
def nexti(self): if len(self.last_stop) == 1: # Restore a single instruction current_inst = self.restore(self.last_stop[0]) last_idx = self.last_stop[0] else: # Restore two branch targets and determine which branch was taken # based on the stop code i1 = self.restore(self.last_stop[0]) i2 = self.restore(self.last_stop[1]) if self.stop_code == DEBUG_STOP: current_inst = i1 last_idx = self.last_stop[0] else: current_inst = i2 last_idx = self.last_stop[1] # If the current instruction is a branch, get the location # of all possible next instructions if isinstance(current_inst, (spu.br, spu.brsl)): next_stop = (self.last_stop[0] + current_inst.I16, ) print 'next br:', next_stop elif isinstance(current_inst, (spu.bra, spu.brasl)): next_stop = (current_inst.I16 - (self.lsa >> 2), ) elif isinstance(current_inst, (spu.brnz, spu.brz, spu.brhnz, spu.brhz)): next_stop = (self.last_stop[0] + 1, self.last_stop[0] + current_inst.I16) elif isinstance(current_inst, (spu.bi, spu.bisled, spu.bisl)): raise Exception( "DebugProcessor does not support branch indirect (bi) instructions" ) else: next_stop = (self.last_stop[0] + 1, ) # TODO: Get rid of last instruction. Do something smarter. last_instruction = (next_stop[0] == (self.debug_idx - 1)) # !!! STOPPED HERE !!! # !!! STILL WRONG !!! if not last_instruction: # Normal instructions and single target branches self.replace(next_stop[0], spu.bra(self.debug_lsa, ignore_active=True)) print 'target (1):', -(self.debug_lsa - ((self.lsa >> 2) + next_stop[0]) ), self.debug_lsa, last_idx, self.lsa self.replace( self.debug_branch, spu.br(-(self.debug_lsa - ((self.lsa >> 2) + next_stop[0])), ignore_active=True)) # Branch target for test-based branch instructions if len(next_stop) == 2: self.replace( next_stop[1], spu.bra(self.debug_target_lsa, ignore_active=True)) print 'target (2):', -(self.debug_target_lsa - ( (self.lsa >> 2) + next_stop[1])), self.debug_target_lsa self.replace( self.debug_target_branch, spu.br(-(self.debug_target_lsa - ((self.lsa >> 2) + next_stop[1])), ignore_active=True)) # self.replace(next_stop, self.debug_stop) self.get_instructions() self.code.print_code() self.resume(self.spe_id) if last_instruction: r = self.join(self.spe_id) r = None else: r = self.wait_debug() self.last_stop = next_stop self.stop_code = r return r
if __name__ == '__main__': code = env.InstructionStream() reg = code.acquire_register() foo = code.acquire_register(reg=1) code.add(code.get_label("FOO")) code.add(spu.il(foo, 0xCAFE)) code.add(spu.ilhu(reg, 0xDEAD)) code.add(spu.iohl(reg, 0xBEEF)) code.add(spu.stqd(reg, code.r_zero, 4)) lbl_loop = code.get_label("LOOP") lbl_break = code.get_label("BREAK") r_cnt = code.gp_return r_stop = code.acquire_register(reg=9) r_cmp = code.acquire_register() code.add(spu.ori(r_cnt, code.r_zero, 0)) code.add(spu.il(r_stop, 5)) code.add(lbl_loop) code.add(spu.ceq(r_cmp, r_cnt, r_stop)) code.add(spu.brnz(r_cmp, code.get_label("BREAK"))) code.add(spu.ai(r_cnt, r_cnt, 1)) code.add(spu.br(code.get_label("LOOP"))) code.add(lbl_break) app = SPUApp(code) app.MainLoop()
code = prgm.get_stream() reg = prgm.acquire_register() foo = prgm.acquire_register(reg_name = 5) code.add(prgm.get_label("FOO")) code.add(spu.il(foo, 0xCAFE)) code.add(spu.ilhu(reg, 0xDEAD)) code.add(spu.iohl(reg, 0xBEEF)) code.add(spu.stqd(reg, code.r_zero, 4)) lbl_loop = prgm.get_label("LOOP") lbl_break = prgm.get_label("BREAK") r_cnt = code.gp_return r_stop = prgm.acquire_register(reg_name = 9) r_cmp = prgm.acquire_register() code.add(spu.ori(r_cnt, code.r_zero, 0)) code.add(spu.il(r_stop, 5)) code.add(lbl_loop) code.add(spu.ceq(r_cmp, r_cnt, r_stop)) code.add(spu.brnz(r_cmp, prgm.get_label("BREAK"))) code.add(spu.ai(r_cnt, r_cnt, 1)) code.add(spu.br(prgm.get_label("LOOP"))) code.add(lbl_break) app = SPUApp(code) app.MainLoop()