def _align_stream(self, length, align): # Return nop's such that length % align = 0 if align % 4 != 0: raise Exception("SPU alignment must be a multiple of 4 bytes") length /= 4 align /= 4 mod = align - (length % align) # need mod instructions to achieve alignment ret = [] if mod % 2 == 0: nop_pair = (spu.nop(self.r_zero, ignore_active = True), spu.lnop(ignore_active = True)) # issue mod / 2 nop/lnop pairs for i in xrange(0, mod / 2): ret.extend(nop_pair) else: # issue an lnop, then (mod - 1) / 2 nop/lnop pairs nop_pair = (spu.lnop(ignore_active = True), spu.nop(self.r_zero, ignore_active = True)) for i in xrange(0, mod / 2): ret.extend(nop_pair) ret.append(spu.lnop(ignore_active = True)) return ret
def _align_stream(self, length, align): # Return nop's such that length % align = 0 if align % 4 != 0: raise Exception("SPU alignment must be a multiple of 4 bytes") length /= 4 align /= 4 mod = align - (length % align) # need mod instructions to achieve alignment ret = [] if mod % 2 == 0: nop_pair = (spu.nop(self.r_zero, ignore_active=True), spu.lnop(ignore_active=True)) # issue mod / 2 nop/lnop pairs for i in xrange(0, mod / 2): ret.extend(nop_pair) else: # issue an lnop, then (mod - 1) / 2 nop/lnop pairs nop_pair = (spu.lnop(ignore_active=True), spu.nop(self.r_zero, ignore_active=True)) for i in xrange(0, mod / 2): ret.extend(nop_pair) ret.append(spu.lnop(ignore_active=True)) return ret
def cache_code(self): """ Add a stop signal with return type 0x2000 (EXIT_SUCCESS) to the end if the instruction stream. (BE Handbook, p. 422). """ # Generate the prologue self._synthesize_prologue() # Don't have a real epilogue. self.add(spu.stop(0x2000)) # self._check_alignment(self._code, 'spu code') # self.exec_module.make_executable(self._code.buffer_info()[0], len(self._code)) # Append our instructions to the prologue's, first making sure the alignment is correct. if len(self._prologue._code) % 2 == 1: # Odd number of instructions self._prologue.add(spu.lnop(0)) self._prologue._code.extend(self._code) self._prologue._check_alignment(self._prologue._code, 'spu prologue') self._epilogue = self self._cached = True return
def _synthesize_prologue(self): """ Setup register 0. """ # Reserve register r0 for the value zero # TODO - technically this is not needed, system sets all regs to 0 self._prologue = [self.lbl_prologue, spu.il(self.r_zero, 0, ignore_active = True), spu.lnop(ignore_active = True)] return
def _synthesize_prologue(self): """ Setup register 0. """ self._prologue = [self.lbl_prologue] # Reserve register r0 for the value zero self._prologue.append(spu.il(self.r_zero, 0, ignore_active=True)) self._prologue.append(spu.lnop(ignore_active=True)) return
def align_code(self, boundary): """ Insert the appropraite nop/lnops to align the next instruction on the byte boudary. boundary must be a multiple of four. """ word_align = boundary / 4 while len(self._code) % word_align: if len(self._code) % 2 == 0: self.add(spu.nop(0), True) else: self.add(spu.lnop(0), True) return
def add(self, inst, optimize_override=False): if not optimize_override and self._optimize: # binary_string_inst = spu.DecToBin(inst) op = 'nop' # if binary_string_inst[0:3] in spu.inst_opcodes: # op = spu.inst_opcodes[binary_string_inst[0:3]] # elif binary_string_inst[0:6] in spu.inst_opcodes: # op = spu.inst_opcodes[binary_string_inst[0:6]] # elif binary_string_inst[0:7] in spu.inst_opcodes: # op = spu.inst_opcodes[binary_string_inst[0:7]] # elif binary_string_inst[0:8] in spu.inst_opcodes: # op = spu.inst_opcodes[binary_string_inst[0:8]] # elif binary_string_inst[0:9] in spu.inst_opcodes: # op = spu.inst_opcodes[binary_string_inst[0:9]] # elif binary_string_inst[0:10] in spu.inst_opcodes: # op = spu.inst_opcodes[binary_string_inst[0:10]] pipeline = inst.cycles[0] if (len(self._code) % 2 == 0) and pipeline == 0: InstructionStream.add(self, inst) elif (len(self._code) % 2 == 1) and pipeline == 1: InstructionStream.add(self, inst) elif (len(self._code) % 2 == 0) and pipeline == 1: InstructionStream.add(self, spu.nop(0)) InstructionStream.add(self, inst) elif (len(self._code) % 2 == 1) and pipeline == 0: InstructionStream.add(self, spu.lnop(0)) InstructionStream.add(self, inst) else: spe.InstructionStream.add(self, inst) # Invalidate the cache self._cached = False return len(self._code)
def add(self, inst, optimize_override = False): if not optimize_override and self._optimize: # binary_string_inst = spu.DecToBin(inst) op = 'nop' # if binary_string_inst[0:3] in spu.inst_opcodes: # op = spu.inst_opcodes[binary_string_inst[0:3]] # elif binary_string_inst[0:6] in spu.inst_opcodes: # op = spu.inst_opcodes[binary_string_inst[0:6]] # elif binary_string_inst[0:7] in spu.inst_opcodes: # op = spu.inst_opcodes[binary_string_inst[0:7]] # elif binary_string_inst[0:8] in spu.inst_opcodes: # op = spu.inst_opcodes[binary_string_inst[0:8]] # elif binary_string_inst[0:9] in spu.inst_opcodes: # op = spu.inst_opcodes[binary_string_inst[0:9]] # elif binary_string_inst[0:10] in spu.inst_opcodes: # op = spu.inst_opcodes[binary_string_inst[0:10]] pipeline = inst.cycles[0] if (len(self._code) % 2 == 0) and pipeline == 0: InstructionStream.add(self, inst) elif (len(self._code) % 2 == 1) and pipeline == 1: InstructionStream.add(self, inst) elif (len(self._code) % 2 == 0) and pipeline == 1: InstructionStream.add(self, spu.nop(0)) InstructionStream.add(self, inst) elif (len(self._code) % 2 == 1) and pipeline == 0: InstructionStream.add(self, spu.lnop(0)) InstructionStream.add(self, inst) else: spe.InstructionStream.add(self, inst) # Invalidate the cache self._cached = False return len(self._code)