class RiscvTestsP(get_wrapper("Assembly")): def start_main(self): return """\ #include "riscv_test.h" #include "riscv-tests/isa/macros/scalar/test_macros.h" RVTEST_RV64UF RVTEST_CODE_BEGIN """ def end_main(self): return """\ TEST_CASE( 1, x0, 0, nop ) TEST_PASSFAIL RVTEST_CODE_END .data RVTEST_DATA_BEGIN TEST_DATA RVTEST_DATA_END""" def outputname(self, name): if not name.endswith(".S"): return "%s.S" % name return name
def emit(self): # Do not touch pointer registers reserved_registers = ["X0", "X1", "X2", "X3", "X4", "X8"] instructions_not_found = [ i for i in self.args.instructions if i not in [ix.name for ix in self.target.isa.instructions.values()] ] if instructions_not_found: raise MicroprobeException( str.format('Instructions {} not available', instructions_not_found)) if not os.path.exists(self.args.output_dir): os.makedirs(self.args.output_dir) valid_instrs = [ i for i in self.target.isa.instructions.values() if i.name in self.args.instructions ] microbenchmarks = [] for instr in valid_instrs: for d in self.args.dependency_distances: cwrapper = get_wrapper('RiscvTestsP') synth = Synthesizer( self.target, # Remove the endless parameter to not generate # an endless loop cwrapper(endless=True), value=0b01010101, ) passes = [ structure.SimpleBuildingBlockPass(self.args.loop_size), instruction.SetRandomInstructionTypePass([instr]), initialization.ReserveRegistersPass(reserved_registers), branch.BranchNextPass(), memory.GenericMemoryStreamsPass([[0, 1024, 1, 32, 1]]), register.DefaultRegisterAllocationPass(dd=d) ] for p in passes: synth.add_pass(p) microbenchmark = instr.name + '_' + str(d) print("Generating %s ..." % microbenchmark) bench = synth.synthesize() synth.save(str.format('{}/{}', self.args.output_dir, microbenchmark), bench=bench) microbenchmarks += [microbenchmark] # Emit a Makefile fragment (tests.d) that identifies all tests # created f = open(str.format('{}/tests.d', self.args.output_dir), 'w') f.write( str.format('# Autogenerated by {}\n', sys.argv[0]) + 'tests = \\\n\t' + '\\\n\t'.join([m for m in microbenchmarks])) f.close()
def _get_wrapper(name): try: return get_wrapper(name) except MicroprobeValueError as exc: raise MicroprobeException( "Wrapper '%s' not available. Check if you have the wrappers " "of the target installed or set up an appropriate " "MICROPROBEWRAPPERS environment variable. Original error was: %s" % (name, str(exc)))
class CInfPpc(get_wrapper("CWrapper")): """A wrapper for the C language with an infinite loop specific for PPC architecture. """ def __init__(self): super(CInfPpc, self).__init__() self._loop_label = None def start_loop(self, instr, dummy_instr_reset, dummy_aligned=False): """ :param instr: :param dummy_aligned: (Default value = False) """ if instr.label is None: instr.set_label("infloop") self._loop_label = instr.label return "" def end_loop(self, dummy_instr): """ :param dummy_instr: """ loop = [] loop.append(self.wrap_ins("b %s" % self._loop_label)) return "\n".join(loop) def infinite(self): # pylint: disable=no-self-use """ """ return True def reserved_registers(self, # pylint: disable=no-self-use dummy_reserved, dummy_target): """ :param dummy_reserved: :param dummy_target: """ return []
class CLoopPpc(get_wrapper("CWrapper")): """A wrapper for the C language with a loop with n iterations specific for PPC architecture. """ def __init__(self, size): """ :param size: """ super(CLoopPpc, self).__init__() self._size = int(size) def start_loop(self, dummy_instr, dummy_instr_reset, dummy_aligned=False): """ :param dummy_instr: :param dummy_aligned: (Default value = False) """ loop = [] loop.append(self.wrap_ins("li 0, %s" % self._size)) loop.append(self.wrap_ins("mtctr 0")) loop.append(self.wrap_ins("infloop:")) return "\n".join(loop) def end_loop(self, dummy_instr): """ :param dummy_instr: """ loop = [] loop.append(self.wrap_ins("bdnz+ infloop")) return "\n".join(loop) def infinite(self): # pylint: disable=no-self-use """ """ return False def reserved_registers(self, dummy_reserved, dummy_target): """ :param dummy_reserved: :param dummy_target: """ raise NotImplementedError
def emit(self): # Reserve a couple of register to control # the branch behavior # # X0 reserved to avoid using constant 0 # X5 will be used to store the local branch pattern # X6 will be used to store the loop count # X7 will be used to store current branch # X8 will be used to store constant 1 (we already have # X0 with constant 0) reserved_registers = ["X0", "X5", "X6", "X7", "X8"] if not os.path.exists(self.args.output_dir): os.makedirs(self.args.output_dir) # Pick some instructions to add between branches valid_instrs = [ i for i in self.target.isa.instructions.values() if i.name in ['ADD_V0', 'MUL_V0', 'LW_V0'] ] valid_instrs_names = [ i.name for i in self.target.isa.instructions.values() if i.name in ['ADD_V0', 'MUL_V0', 'LW_V0'] ] # Add conditional branches branch_instrs_names = [ i.name for i in self.target.isa.instructions.values() if i.branch_conditional ] branch_instrs = [ i for i in self.target.isa.instructions.values() if i.branch_conditional ] microbenchmarks = [] cwrapper = get_wrapper('RiscvTestsP') synth = Synthesizer( self.target, cwrapper(endless=True), value=0b01010101, ) # Add a building block p = structure.SimpleBuildingBlockPass(self.args.loop_size) synth.add_pass(p) # Reserve registers p = initialization.ReserveRegistersPass(reserved_registers) synth.add_pass(p) # Set instruction type random = self.args.random_ins if not random: sequence = [] for elem in branch_instrs: sequence.extend(valid_instrs) sequence.append(elem) p = instruction.SetInstructionTypeBySequencePass(sequence) else: p = instruction.SetRandomInstructionTypePass([ self.target.isa.instructions[elem] for elem in valid_instrs_names + branch_instrs_names ]) synth.add_pass(p) p = initialization.InitializeRegistersPass(value=RNDINT, fp_value=RNDINT) synth.add_pass(p) # Initialize X5 to local branch pattern p = initialization.InitializeRegisterPass( "X5", int(self.args.local_branch_pattern, 2)) synth.add_pass(p) # Initialize X6 to 0 (loop count) p = initialization.InitializeRegisterPass("X6", 0) synth.add_pass(p) # Initialize X7 to current branch p = initialization.AddInitializationAssemblyPass("andi x7, x5, 1") synth.add_pass(p) # Initialize X8 to 1 p = initialization.InitializeRegisterPass("X8", 1) synth.add_pass(p) # # Set operands of the conditional branch instructions # # Operand 1 of all branches will be X7, which contains the # current branch value (which changes every iteration) p = instruction.SetInstructionOperandsByOpcodePass( branch_instrs_names, 1, self.target.isa.registers["X7"], ) synth.add_pass(p) # Operand 2 of all branches will be X0 (0) / X8 (1) # based on the global pattern provided global_pattern_regs = [] for char in self.args.global_branch_pattern: if char == "0": global_pattern_regs.append(self.target.isa.registers["X0"]) else: global_pattern_regs.append(self.target.isa.registers["X8"]) p = instruction.SetInstructionOperandsByOpcodePass( branch_instrs_names, 2, global_pattern_regs) synth.add_pass(p) # Randomize branches for BGT 0 every N branches p = branch.RandomizeByTypePass( branch_instrs, # instructions to replace self.target.isa.instructions['BGE_V0'], # new instruction self.args.random_branch, # every N instructions or if a value # between [0,1] the probability of a # branch to be random "slli @@BRREG@@, @@REG@@, @@COUNT@@", # randomization code # to add before branch distance=30, # distance between randomization code and branch musage=62, # max. time @@REG@@ can be used before reset. Do not # set above 63 reset=('rnd', (-0x7ff, 0x7ff)) # method to randomize register ) synth.add_pass(p) # At the end of each iteration, update the loop count if not self.args.switch_pattern: p = initialization.AddFinalizationAssemblyPass( "addi x6, x6, 1 \n" + # Add +1 # Compare and reset based on pattern length "slti x7, x6, %d\n" % min(64, len(self.args.local_branch_pattern)) + "bne x7, x0, 8 \n" + # "addi x6, x0, 0 \n" + # Reset to zero "addi x0, x0, 0" # nop ) synth.add_pass(p) else: p = initialization.AddFinalizationAssemblyPass( "addi x6, x6, 1 \n" + # Add +1 # Compare and reset based on pattern length "slti x7, x6, %d\n" % min(64, len(self.args.local_branch_pattern)) + "bne x7, x0, 12 \n" + # "addi x6, x0, 0 \n" + # Reset to zero "xori x5, x5, -1 \n" + # switch branch pattern "addi x0, x0, 0" # nop ) synth.add_pass(p) # At the end of each iteration, update the current # branch register based on loop count p = initialization.AddFinalizationAssemblyPass("srl x7, x5, x6 \n" + "andi x7, x7, 1") synth.add_pass(p) # Model memory operations to ensure correctness p = memory.GenericMemoryStreamsPass([[0, 1024, 1, 32, 1, 0, (1, 0)]]) synth.add_pass(p) # Model dependency distance (no dependencies) p = register.DefaultRegisterAllocationPass(dd=0) synth.add_pass(p) # Set target of branches (regarless of taken not taken, # branch to next instruction) p = address.UpdateInstructionAddressesPass() synth.add_pass(p) braid = self.args.braid if braid: p = branch.BranchBraidNextPass(force=True) synth.add_pass(p) else: p = branch.BranchNextPass(force=True) synth.add_pass(p) microbenchmark = "branch_%s_%s_%d" % (self.args.global_branch_pattern, self.args.local_branch_pattern, self.args.switch_pattern) print("Generating %s ..." % microbenchmark) bench = synth.synthesize() synth.save(str.format('{}/{}', self.args.output_dir, microbenchmark), bench=bench) print(cwrapper().outputname( str.format('{}/{}', self.args.output_dir, microbenchmark)) + " saved!") microbenchmarks += [microbenchmark] # Emit a Makefile fragment (tests.d) that identifies all tests # created f = open(str.format('{}/tests.d', self.args.output_dir), 'w') f.write( str.format('# Autogenerated by {}\n', sys.argv[0]) + 'tests = \\\n\t' + '\\\n\t'.join([m for m in microbenchmarks])) f.close()
def emit(self): # Do not touch pointer registers reserved_registers = ["X0", "X1", "X2", "X3", "X4", "X8"] instructions_not_found = [ i for i in self.args.instructions if i not in [ix.name for ix in self.target.isa.instructions.values()] ] if instructions_not_found: raise MicroprobeException( str.format('Instructions {} not available', instructions_not_found)) if not os.path.exists(self.args.output_dir): os.makedirs(self.args.output_dir) valid_instrs = [ i for i in self.target.isa.instructions.values() if i.name in self.args.instructions ] # Generate permutations of instruction sequences and randomize order random.seed(rs) instr_seq_count = len(valid_instrs) print("Instruction sequence count: " + str(instr_seq_count)) # Select instruction sequence permutations if (self.args.num_permutations > math.factorial( min(instr_seq_count, MAX_INSTR_PERM_LENGTH))): print("ERROR: Selected sequences cannot exceed num. permutations") sys.exit() # Check if number of instructions exceeds maximum permutation length # -- Fix to prevent permutation function from hanging if (instr_seq_count > MAX_INSTR_PERM_LENGTH): print("WARNING: Instruction sequence is too long...\ Selecting from reduced number of permutations!!") reduced_instrs = valid_instrs[0:MAX_INSTR_PERM_LENGTH] reduced_instr_seq = list( it.permutations(reduced_instrs, len(reduced_instrs))) random.shuffle(reduced_instr_seq) selected_valid_instr_seq = reduced_instr_seq[:][0:self.args. num_permutations] # Append remaining instructions to each of the sequences in list rem_instr_seq = valid_instrs[MAX_INSTR_PERM_LENGTH:instr_seq_count] for s in range(0, len(selected_valid_instr_seq)): selected_valid_instr_seq[s] = list( selected_valid_instr_seq[s]) + rem_instr_seq else: # Generate complete list of permutations valid_instr_seq = list(it.permutations(valid_instrs)) random.shuffle(valid_instr_seq) selected_valid_instr_seq = valid_instr_seq[:][0:self.args. num_permutations] microbenchmarks = [] # Loop over selected sequence permutations for vi in range(0, len(selected_valid_instr_seq)): vi_seq = selected_valid_instr_seq[:][vi] for d in self.args.dependency_distances: microbenchmark = '' cwrapper = get_wrapper('RiscvTestsP') synth = Synthesizer( self.target, # Remove the endless parameter to not generate # an endless loop cwrapper(endless=True), value=0b01010101, ) passes = [ structure.SimpleBuildingBlockPass(self.args.loop_size), instruction.SetInstructionTypeBySequencePass(vi_seq), initialization.ReserveRegistersPass(reserved_registers), branch.BranchNextPass(), memory.GenericMemoryStreamsPass([[0, 1024, 1, 32, 1]]), register.DefaultRegisterAllocationPass(dd=d) ] for p in passes: synth.add_pass(p) if (not self.args.microbenchmark_name): for instr in vi_seq: microbenchmark = microbenchmark +instr.name + '_DD' + str(d) else: microbenchmark = self.args.microbenchmark_name \ + '_DD' + str(d) + '_' + str(vi) print("Generating %s ..." % microbenchmark) bench = synth.synthesize() synth.save(str.format('{}/{}', self.args.output_dir, microbenchmark), bench=bench) microbenchmarks += [microbenchmark] # Print out microbenchmark names print("Generating microbenchmarks named:") print(microbenchmarks) # Emit a Makefile fragment (tests.d) that identifies all tests # created f = open( str.format('{}/' + self.args.microbenchmark_name + '_tests.d', self.args.output_dir), 'w') f.write( str.format('# Autogenerated by {}\n', sys.argv[0]) + 'tests = \\\n\t' + '\\\n\t'.join([m for m in microbenchmarks])) f.close()
def emit(self): # Reserve a couple of register to control # the branch behavior # # X5 will be used to store the local branch pattern # X6 will be used to store the loop count # X7 will be used to store current branch # X8 will be used to store constant 1 (we already have # X0 with constant 0) reserved_registers = ["X5", "X6", "X7"] if not os.path.exists(self.args.output_dir): os.makedirs(self.args.output_dir) # Pick some instructions to add between branches valid_instrs = [ i.name for i in self.target.isa.instructions.values() if i.name in ['ADD_V0', 'MUL_V0'] ] # Add conditional branches branch_instrs = [ i.name for i in self.target.isa.instructions.values() if i.branch_conditional ] microbenchmarks = [] cwrapper = get_wrapper('RiscvTestsP') synth = Synthesizer( self.target, cwrapper(endless=True), value=0b01010101, ) # Add a building block p = structure.SimpleBuildingBlockPass(self.args.loop_size) synth.add_pass(p) # Reserve registers p = initialization.ReserveRegistersPass(reserved_registers) synth.add_pass(p) # Set instruction type p = instruction.SetRandomInstructionTypePass(valid_instrs + branch_instrs) synth.add_pass(p) # Initialize X5 to local branch pattern p = initialization.InitializeRegisterPass( "X5", int(self.args.local_branch_pattern, 2)) synth.add_pass(p) # Initialize X6 to 0 (loop count) p = initialization.InitializeRegisterPass("X6", 0) synth.add_pass(p) # Initialize X7 to current branch p = initialization.AddInitializationAssemblyPass("andi x7, x5, 1") synth.add_pass(p) # Initialize X8 to 1 p = initialization.InitializeRegisterPass("X8", 1) synth.add_pass(p) # # Set operands of the conditional branch instructions # # Operand 1 of all branches will be X7, which contains the # current branch value (which changes every iteration) p = instruction.SetInstructionOperandsByOpcodePass( branch_instrs, 1, self.target.isa.registers["X7"], ) synth.add_pass(p) # Operand 2 of all branches will be X0 (0) / X8 (1) # based on the global pattern provided global_pattern_regs = [] for char in self.args.global_branch_pattern: if char == "0": global_pattern_regs.append(self.target.isa.registers["X0"]) else: global_pattern_regs.append(self.target.isa.registers["X8"]) p = instruction.SetInstructionOperandsByOpcodePass( branch_instrs, 2, global_pattern_regs) synth.add_pass(p) # Set target of branches (regarless of taken not taken, # branch to next instruction) p = branch.BranchNextPass() synth.add_pass(p) # At the end of each iteration, update the loop count if not self.args.switch_pattern: p = initialization.AddFinalizationAssemblyPass( "addi x6, x6, 1 \n" + # Add +1 # Compare and reset based on pattern length "slti x7, x6, %d\n" % min(64, len(self.args.local_branch_pattern)) + "bne x7, x0, 8 \n" + # "addi x6, x0, 0 \n" + # Reset to zero "addi x0, x0, 0" # nop ) synth.add_pass(p) else: p = initialization.AddFinalizationAssemblyPass( "addi x6, x6, 1 \n" + # Add +1 # Compare and reset based on pattern length "slti x7, x6, %d\n" % min(64, len(self.args.local_branch_pattern)) + "bne x7, x0, 12 \n" + # "addi x6, x0, 0 \n" + # Reset to zero "xori x5, x5, -1 \n" + # switch branch pattern "addi x0, x0, 0" # nop ) synth.add_pass(p) # At the end of each iteration, update the current # branch register based on loop count p = initialization.AddFinalizationAssemblyPass("srl x7, x5, x6") synth.add_pass(p) # Model memory operations to ensure correctness p = memory.GenericMemoryStreamsPass([[0, 1024, 1, 32, 1]]) synth.add_pass(p) # Model dependency distance (no dependencies) p = register.DefaultRegisterAllocationPass(dd=0) synth.add_pass(p) microbenchmark = "branch_%s_%s_%d" % (self.args.global_branch_pattern, self.args.local_branch_pattern, self.args.switch_pattern) print("Generating %s ..." % microbenchmark) bench = synth.synthesize() synth.save(str.format('{}/{}', self.args.output_dir, microbenchmark), bench=bench) microbenchmarks += [microbenchmark] # Emit a Makefile fragment (tests.d) that identifies all tests # created f = open(str.format('{}/tests.d', self.args.output_dir), 'w') f.write( str.format('# Autogenerated by {}\n', sys.argv[0]) + 'tests = \\\n\t' + '\\\n\t'.join([m for m in microbenchmarks])) f.close()
class RiscvTestsP(get_wrapper("Assembly")): def __init__(self, endless=False, reset=False): self._endless = endless self._reset = reset super(RiscvTestsP, self).__init__() def headers(self): return """\ /* Headers */ #include "riscv_test.h" #include "riscv-tests/isa/macros/scalar/test_macros.h" """ def start_main(self): return """\ /* Start Main */ RVTEST_RV64UF RVTEST_CODE_BEGIN """ def outputname(self, name): """ :param name: """ if not name.endswith(".S"): return "%s.S" % name return name def post_var(self): return "".join("reset:") def start_loop(self, instr, instr_reset, dummy_aligned=True): """ :param instr: :param instr_reset: :param dummy_aligned: (Default value = True) """ start_loop = ["/* Building block start */\n"] if not self._endless: return "\n".join(start_loop) if self._reset: instr_reset.add_comment("Loop start reseting") if not instr_reset.label: instr_reset.set_label("reset") self._loop_label = "reset" else: self._loop_label = instr_reset.label else: instr.add_comment("Loop start") if not instr.label: instr.set_label("infloop") self._loop_label = "infloop" else: self._loop_label = instr.label return "\n".join(start_loop) def end_loop(self, dummy_instr): """ """ if not self._endless: return "/* Loop End */" loop = ["/* Loop End */"] loop.append(self.wrap_ins("j %s" % self._loop_label)) return "\n".join(loop) def end_main(self): return """\ /* End Main */ TEST_CASE( 1, x0, 0, nop ) TEST_PASSFAIL RVTEST_CODE_END .data RVTEST_DATA_BEGIN TEST_DATA RVTEST_DATA_END """ def declare_global_var(self, var): if var.align: return ".comm %s, %d, %d\n" % (var.name, var.size, var.align) else: return ".comm %s, %d\n" % (var.name, var.size)
class CPSynchStepMultithread(get_wrapper("CWrapper")): """ """ def __init__( self, synctype, steps, bias, dithering=0, delay=0, master_delay=0, reset=False ): """ :param synctype: :param steps: :param bias: :param dithering: (Default value = 0) """ super(CPSynchStepMultithread, self).__init__(reset=reset) self._synctype = synctype self._steps = steps self._bias = bias self._dithering = dithering self._delay = delay self._master_delay = master_delay with open( os.path.join( _MODULE_DIR, "CPSynchStepMultithread.headers" ), 'r') as textfile: for header in textfile.readlines(): self._extra_headers.append(header[:-1]) def headers(self): """ """ header = [] for elem in self._extra_headers: header.append(elem) return "\n".join(header) def start_main(self): """ """ main = [super(CPSynchStepMultithread, self).start_main()] with open( os.path.join( _MODULE_DIR, "CPSynchStepMultithread.start_main" ), 'r') as textfile: for elem in textfile.readlines(): main.append(elem[:-1]) return "\n".join(main) def post_var(self): """ """ mstr = [self.wrap_ins(ins) for ins in self.target.get_context()] if self._reset: mstr.append(self.wrap_ins("infloop:")) return "".join(mstr) def start_loop(self, dummy_instr, dummy_instr_reset, dummy_aligned=False): """ :param dummy_instr: :param dummy_aligned: (Default value = False) """ loop = [] if not self._reset: loop.append(self.wrap_ins("infloop:")) with open( os.path.join( _MODULE_DIR, "CPSynchStepMultithread.start_loop" ), 'r') as textfile: for elem in textfile.readlines(): loop.append(elem[:-1]) treplace = [] if self._synctype == '4ms': treplace.append(("$SYNCHMASK1$", "MASK_4US_1")) treplace.append(("$SYNCHMASK2$", "MASK_4US_2")) else: treplace.append(("$SYNCHMASK1$", "MASK_1S_1")) treplace.append(("$SYNCHMASK2$", "MASK_1S_2")) treplace.append(("$SYNCHBIAS$", str(self._bias))) treplace.append(("$MASTERSTEPS$", self.wrap_ins("li 0, %s" % max(self._steps // 2, 1)))) treplace.append(("$SLAVESTEPS$", self.wrap_ins("li 0, %s" % self._steps))) master_delay = [] for dummy_idx in range(0, self._master_delay): master_delay.append(self.wrap_ins(self.target.nop())[:-1]) master_delay = "\n".join(master_delay) treplace.append(("$MASTERDELAY$", master_delay)) delay = [] for dummy_idx in range(0, self._delay): delay.append(self.wrap_ins(self.target.nop())[:-1]) delay = "\n".join(delay) treplace.append(("$DELAY$", delay)) for idx, line in enumerate(loop): for orig, new in treplace: line = line.replace(orig, new) loop[idx] = line loop.append(self.wrap_ins("mtctr 0")) loop.append(self.wrap_ins("steploop:")) return "\n".join(loop) def outputname(self, name): # pylint: disable=no-self-use """ :param name: """ if not name.endswith(".c"): return "%s.c" % name return name def end_loop(self, dummy_ins): """ :param dummy_ins: """ instr_list = [] for dummy in range(0, self._dithering): instr_list.append(self.wrap_ins(self.target.nop())) instr_list.extend([self.wrap_ins("bdnz+ steploop"), self.wrap_ins("b infloop")]) return "\n".join(instr_list) def reserved_registers(self, reserved, target): """ :param reserved: :param target: """ reserved = super( CPSynchStepMultithread, self ).reserved_registers( reserved, target ) reserved.append(target.registers["GPR1"]) reserved.append(target.registers["GPR9"]) reserved.append(target.registers["GPR30"]) reserved.append(target.registers["GPR31"]) reserved.append(target.registers["GPR2"]) reserved.append(target.registers["GPR8"]) reserved.append(target.registers["GPR10"]) return reserved
class CSpecialPpc(get_wrapper("CWrapper")): """A wrapper for the C language specfific for PPC architecture, special for some experiments. """ def start_loop(self, dummy_instr, dummy_instr_reset, dummy_aligned=False): """ :param dummy_instr: :param dummy_aligned: (Default value = False) """ # special prologue loop = [] loop.append(self.wrap_ins("li 3, 0")) loop.append(self.wrap_ins("infloop:")) return "\n".join(loop) def end_loop(self, dummy_instr): """ :param dummy_instr: """ # special epilogue loop = [] loop.append(self.wrap_ins("addi 3,3,1")) loop.append(self.wrap_ins("mfspr 4, 1023")) loop.append(self.wrap_ins("andi. 4, 4, 3")) loop.append(self.wrap_ins("slwi 4, 4, 3")) loop.append(self.wrap_ins("ori 4, 4, 0x20")) loop.append(self.wrap_ins("mtspr 276,4")) loop.append(self.wrap_ins("isync")) loop.append(self.wrap_ins("mtspr 277,3")) loop.append(self.wrap_ins("isync")) loop.append(self.wrap_ins("b infloop")) return "\n".join(loop) def infinite(self): # pylint: disable=no-self-use """ """ return True def reserved_registers(self, # pylint: disable=no-self-use dummy_reserved, dummy_target): """ :param dummy_reserved: :param dummy_target: """ # reserved registers # raise NotImplementedError rlist = [] # rlist.append(microprobe.arch.ppc._powerpc_registers["GPR3"]) # rlist.append(microprobe.arch.ppc._powerpc_registers["GPR4"]) # rlist.append(microprobe.arch.ppc._powerpc_registers["GPR10"]) # rlist.append(microprobe.arch.ppc._powerpc_registers["GPR11"]) # rlist.append(microprobe.arch.ppc._powerpc_registers["GPR12"]) return rlist def declare_global_var(self, var): # pylint: disable=no-self-use """ :param var: """ # declaration without alignment if var.array(): return "extern THREAD %s[%d];\n" % (var.name, var.size) else: return "extern THREAD %s;\n" % (var.name) def headers(self): # pylint: disable=no-self-use """ """ # the special header you wanted header = [] header.append('#include "common.h"') return "\n".join(header) def init_global_var(self, # pylint: disable=no-self-use dummy_var, dummy_value): """ :param dummy_var: :param dummy_value: """ # No initializations at all return "" def start_main(self): """ """ main = [] main.append("void %s(u64* parm_array)" % self._name) main.append("{") return "\n".join(main) def __init__(self, name): """ :param name: """ super(CSpecialPpc, self).__init__() self._max_array_var = None self._max_array_var_value = None self._name = name
class CInfPpcSingleLiteral(get_wrapper("CWrapper")): """A wrapper for the C language with an infinite loop specific for PPC architecture. """ def start_loop(self, instr, dummy_instr_reset, dummy_aligned=False): """ :param instr: :param dummy_aligned: (Default value = False) """ self._loop = 1 loop = [] loop.append("__asm__(") instr.set_label("infloop") return "\n".join(loop) def end_loop(self, dummy_instr): """ :param dummy_instr: """ loop = [] loop.append(self.wrap_ins("b infloop")) loop.append(");") return "\n".join(loop) def infinite(self): # pylint: disable=no-self-use """ """ return True def reserved_registers(self, # pylint: disable=no-self-use dummy_reserved, dummy_target): """ :param dummy_reserved: :param dummy_target: """ return [] def wrap_ins(self, instr): """ :param instr: """ if self._loop: ins = ["\""] ins.append(instr.assembly()) ins.append("\\n\"") return " ".join(ins) else: ins = [] ins.append("__asm__(\"") ins.append(instr.assembly()) ins.append("\");") return " ".join(ins)