def __init__(self, instrs, prepend=None, allow_registers=None): """ :param instrs: """ super(SetInstructionTypeBySequencePass, self).__init__() for instr in instrs: if not isinstance(instr, InstructionType): raise MicroprobeCodeGenerationError( "Invalid sequence definition. '%s' is not an instruction" " type " % instr) self._sequence = instrs self._func = getnextf(itertools.cycle(instrs)) self._description = "Repeat the instruction sequence '%s'" % \ ([instruction.name for instruction in self._sequence]) if prepend is None: prepend = [] self._prepend = prepend self._aregs = [] if allow_registers is not None: self._aregs = allow_registers
def __init__(self, opcodes, operand_pos, value, force=False): """ :param opcodes: :param operand_pos: :param value: """ super(SetInstructionOperandsByOpcodePass, self).__init__() self._description = "Set operand %d of instructions with opcode " \ "'%s' to value: '%s'" % (operand_pos, opcodes, value) if isinstance(opcodes, str): self._opcodes = [opcodes] else: self._opcodes = opcodes self._pos = operand_pos self._base_value = value self._force = force if not isinstance(value, list): def idem(): """Return a constant.""" return value self._value = idem else: self._value = getnextf(itertools.cycle(value))
def check(self, building_block, dummy_target): """ :param building_block: :param dummy_target: """ pass_ok = True func = getnextf(itertools.cycle(self._sequence)) for bbl in building_block.cfg.bbls: for instr in bbl.instrs: pass_ok = pass_ok and (instr.architecture_type == func()) return pass_ok
def declare_global_var(self, var): """ :param var: """ align = var.align if align is None or align is 0: align = "" else: align = " __attribute__ ((aligned (%d)))" % align if var.array(): if var.value is not None: valuestr = "" value = var.value if not isinstance(value, list): value = [value] get_value = getnextf(itertools.cycle(value)) for dummy_idx in range(var.elems): value = get_value() if callable(value): value = value() valuestr = "%s%s," % (valuestr, value) return "%s %s[%d] %s = {%s};\n" % (var.type, var.name, var.size, align, valuestr) else: return "%s %s[%d] %s;\n" % (var.type, var.name, var.size, align) else: if var.value is not None: return "%s %s %s = %s;\n" % (var.type, var.name, align, var.value) else: return "%s %s %s;\n" % (var.type, var.name, align)
def __init__(self, sequences, max_size=None): """ :param sequences: :type sequences: :param max_size: :type max_size: """ super(SetInstructionTypeByAlternatingSequencesPass, self).__init__() self._sequences = [] self._max_size = max_size total_size = sum([elem[1] for elem in sequences]) max_segment_size = max_size // (2 * len(sequences)) if max_size is None: max_size = total_size * (len(sequences) + 1) for idx, sequence in enumerate(sequences): extra = 0 iterations = 1 modulo = len(sequence[0]) length = min(sequence[1], max_segment_size) length = (length // modulo) * modulo if length == 0: length = modulo if (length * iterations) + extra != sequence[1]: iterations = sequence[1] // length extra = sequence[1] % length assert (length * iterations) + extra == sequence[1] self._sequences.append((getnextf(itertools.cycle(sequence[0])), length, iterations, extra)) LOG.debug( "Sequence: %d - %s, Length: %d, " "Iterations: %d, Extra: %d ", idx, ",".join([elem.name for elem in sequence[0]]), length, iterations, extra)
def check(self, building_block, dummy_target): """ :param building_block: :param dummy_target: """ if isinstance(self._base_value, list): self._value = getnextf(itertools.cycle(self._base_value)) for bbl in building_block.cfg.bbls: for instr in bbl.instrs: if instr.opcode in self._opcodes: if instr.operands()[self._pos].value != self._value(): return False return True
def regular_seq(items): """ :param items: :type items: """ total = 0 for item, weight in items.items(): total = total + weight sequence = [] for idx in range(0, total): for item, weight in items.items(): if weight == 0: continue every = (total // weight) - 1 if every == 0: sequence.append(item) elif idx % every == 0: sequence.append(item) return getnextf(itertools.cycle(sequence))
def binary(self, args, asm_args=None): LOG.debug("Start specific RISC-V codification") # Check if fixing is needed fix_needed = False fix_fields = ['sb_imm5', 's_imm5'] base_fields = ['sb_imm7', 's_imm7'] for fix_field in fix_fields: if fix_field in [field.name for field in self.format.fields]: fix_needed = True break if not fix_needed: long_str = super(RISCVInstruction, self).binary(args, asm_args=asm_args) assert len(long_str) in [32], len(long_str) LOG.debug("End specific RISC-V codification") return long_str next_operand_value = getnextf(iter(args)) newargs = [] for op_descriptor, field in zip(list(self.operands.items()), self.format.fields): dummy_fieldname, op_descriptor = op_descriptor operand, dummy = op_descriptor LOG.debug("Field: %s", field) LOG.debug("Operand: %s", operand) if (operand.constant and (field.name not in fix_fields + base_fields)): if field.default_show: arg = next_operand_value() newargs.append(arg) continue if field.name not in fix_fields + base_fields: LOG.debug("Not fixing field: %s", field.name) arg = next_operand_value() newargs.append(arg) continue if field.name in base_fields: arg = next_operand_value() value = int(arg.type.codification(arg.value)) value_coded = int_to_twocs(value, 12) assert twocs_to_int(value_coded, 12) == value newarg = InstructionOperandValue(_7BITS_OPERAND_DESCRIPTOR) newarg.set_value((value_coded & 0xFE0) >> 5) if field.name == "sb_imm7": sb_imm5_value = (value_coded & 0x1F) elif field.name == "s_imm7": s_imm5_value = (value_coded & 0x1F) else: raise NotImplementedError LOG.debug("Set field '%s' value: %s --> %s", field.name, value, (value_coded & 0xFE0) >> 5) newargs.append(newarg) # Assume variable are previously set if field.name in fix_fields: newarg = InstructionOperandValue(_5BITS_OPERAND_DESCRIPTOR) if field.name == "sb_imm5": value_fixed = sb_imm5_value elif field.name == "s_imm5": value_fixed = s_imm5_value else: raise NotImplementedError(field.name) LOG.debug("Set field '%s' value: %s --> %s", field.name, value, value_fixed) newarg.set_value(value_fixed) newargs.append(newarg) LOG.debug("Args: %s, %s", args, newargs) long_str = super(RISCVInstruction, self).binary(newargs, asm_args=args) assert len(long_str) in [16, 32, 48], len(long_str) LOG.debug("End specific RISC-V codification") return long_str
def __init__(self, size, instrs1, ipc1, dep1, instrs2, ipc2, dep2, freqhz, system_freq_mhz): """ :param size: :param instrs1: :param ipc1: :param dep1: :param instrs2: :param ipc2: :param dep2: :param freqhz: :param system_freq_mhz: """ super(DIDTSimplePass, self).__init__() LOG.debug("IPC: %s, %s ", ipc1, ipc2) LOG.debug("FREQ: %s, %s", freqhz, system_freq_mhz) cycletime = 1.0 / (system_freq_mhz * 1000000) period = 1.0 / (freqhz) cycles = (period / 2) / cycletime LOG.debug("TIMES: %s %s %s", cycletime, period, cycles) nins1 = cycles * ipc1 nins2 = cycles * ipc2 self._nins1 = int(nins1) self._nins2 = int(nins2) if self._nins1 < 1: self._nins1 = 1 LOG.warning("Warning 1 a single instruction more than the period") if self._nins2 < 1: self._nins2 = 1 LOG.warning("Warning 2 a single instruction more than the period") LOG.debug("INS %s %s", nins1, nins2) # seq1len = len(instrs1) # seq2len = len(instrs2) # repeat1 = (size/2)/seq1len # repeat2 = (size/2)/seq2len # Compute iterations in each sequence self._loop1 = int(nins1 / (size / 2)) self._loop2 = int(nins2 / (size / 2)) LOG.debug(" %f%% deviation in loop1 size ", ((abs(self._loop1 - (nins1 / (size / 2))) / (nins1 / (size / 2))) * 100)) LOG.debug(" %f%% deviation in loop2 size ", ((abs(self._loop2 - (nins2 / (size / 2))) / (nins2 / (size / 2))) * 100)) LOG.debug("LOOP %s %s", self._loop1, self._loop2) self._size = size / 2 self._func1 = getnextf(itertools.cycle(instrs1)) self._func2 = getnextf(itertools.cycle(instrs2)) self._dep1 = dep1 self._dep2 = dep2
def binary(self, args, dummy_asm_args=None): LOG.debug("Start specific PowerPC codification") # Check if fixing is needed fix_needed = False fix_fields = [ 'SH0', 'CX', 'AX', 'BX', 'TX', 'SX', 'MB6', 'ME6', 'SPR', 'D_14dw', 'D_14sw', 'D_14qw2', 'Dd0', 'Dd2', 'dc', 'dm' ] base_fields = [ 'SH6_5', 'C', 'A', 'Ap', 'B', 'S', 'T', 'TP', 'Dd1', 'dx' ] for fix_field in fix_fields: if fix_field in [field.name for field in self.format.fields]: fix_needed = True break if not fix_needed: long_str = super(PowerInstruction, self).binary(args) assert len(long_str) == 32, \ "Bad PowerPC codification. Length: %d " % len( long_str) LOG.debug("End specific PowerPC codification") return long_str next_operand_value = getnextf(iter(args)) newargs = [] for op_descriptor, field in zip(list(self.operands.items()), self.format.fields): dummy_fieldname, op_descriptor = op_descriptor operand, dummy = op_descriptor LOG.debug("Field: %s", field) LOG.debug("Operand: %s", operand) if (operand.constant and (field.name not in fix_fields + base_fields)): if field.default_show: arg = next_operand_value() newargs.append(arg) continue if field.name not in fix_fields + base_fields: LOG.debug("Not fixing field: %s", field.name) arg = next_operand_value() newargs.append(arg) continue if field.name in base_fields: arg = next_operand_value() value = int(arg.type.codification(arg.value)) if field.name == 'SH6_5': sh0_value = (value & 0x20) >> 5 newarg = InstructionOperandValue(_5BITS_OPERAND_DESCRIPTOR) newarg.set_value(value & 0x1F) elif field.name == "A": ax_value = (value & 0x20) >> 5 newarg = InstructionOperandValue(_5BITS_OPERAND_DESCRIPTOR) newarg.set_value(value & 0x1F) elif field.name == "Ap": ax_value = (value & 0x20) >> 5 newarg = InstructionOperandValue(_5BITS_OPERAND_DESCRIPTOR) newarg.set_value(value & 0x1F) elif field.name == "B": bx_value = (value & 0x20) >> 5 newarg = InstructionOperandValue(_5BITS_OPERAND_DESCRIPTOR) newarg.set_value(value & 0x1F) elif field.name == "C": cx_value = (value & 0x20) >> 5 newarg = InstructionOperandValue(_5BITS_OPERAND_DESCRIPTOR) newarg.set_value(value & 0x1F) elif field.name == "T": tx_value = (value & 0x20) >> 5 newarg = InstructionOperandValue(_5BITS_OPERAND_DESCRIPTOR) newarg.set_value(value & 0x1F) elif field.name in "TP": tx_value = (value & 0b100000) >> 5 newarg = InstructionOperandValue(_5BITS_OPERAND_DESCRIPTOR) newarg.set_value((value & 0b011111) >> 1) elif field.name == "S": sx_value = (value & 0x20) >> 5 newarg = InstructionOperandValue(_5BITS_OPERAND_DESCRIPTOR) newarg.set_value(value & 0x1F) elif field.name == "dx": dm_value = (value >> 5) & 0b1 dc_value = (value >> 6) & 0b1 newarg = InstructionOperandValue(_5BITS_OPERAND_DESCRIPTOR) newarg.set_value(value & 0x1F) elif field.name == "Dd1": value = int_to_twocs(value, 16) dd0_value = value >> 6 dd2_value = value & 0b1 newarg = InstructionOperandValue(_5BITS_OPERAND_DESCRIPTOR) newarg.set_value((value >> 1) & 0b11111) else: raise NotImplementedError newargs.append(newarg) LOG.debug("Set field value: %s --> %s", value, newarg.value) # Assume variable are previously set if field.name in fix_fields: newarg = InstructionOperandValue(_1BIT_OPERAND_DESCRIPTOR) if field.name == 'SH0': value = sh0_value elif field.name == "AX": value = ax_value elif field.name == "BX": value = bx_value elif field.name == "CX": value = cx_value elif field.name == "TX": value = tx_value elif field.name == "SX": value = sx_value elif field.name == "dm": value = dm_value elif field.name == "dc": value = dc_value elif field.name in ["MB6", "ME6"]: arg = next_operand_value() newarg = arg.copy() value = int(arg.type.codification(arg.value)) value = ((value & 0x1F) << 1) | ((value & 0x20) >> 5) elif field.name in ["SPR"]: arg = next_operand_value() newarg = InstructionOperandValue( _10BITS_OPERAND_DESCRIPTOR) value = int(arg.type.codification(arg.value)) value = ((value & 0x1F) << 5) | ((value & 0x3E0) >> 5) elif field.name in [ 'D_14dw', 'D_14sw', 'D_14qw2', ]: arg = next_operand_value() # newarg = arg.copy() newarg = InstructionOperandValue( _14BITS_OPERAND_DESCRIPTOR) value = int(arg.type.codification(arg.value)) value = value >> 2 elif field.name == "Dd0": newarg = arg.copy() value = dd0_value elif field.name == "Dd2": newarg = arg.copy() value = dd2_value else: raise NotImplementedError LOG.debug("Set field to value: %s", value) newarg.set_value(value) newargs.append(newarg) LOG.debug("New args: %s", newargs) long_str = super(PowerInstruction, self).binary(newargs, asm_args=args) assert len(long_str) == 32, "Bad PowerPC codification. Length: %d " \ % len(long_str) LOG.debug("End specific PowerPC codification") return long_str
def declare_global_var(self, var): """ :param var: """ section_name = ".data.microprobe.data.%s" % var.name section_address = var.address.displacement if var.address.base_address == "code": section_address += 0 elif var.address.base_address == "data": section_address += 0 else: section_address = None # raise NotImplementedError(str(var.address)) # make sure we always have the same state random = Random() random.seed(10) if var.array(): typesize = var.size // var.elems else: typesize = var.size str_fmt = "%%0%dx" % (typesize * 2) myvalue = var.value if myvalue is None: if var.array(): myvalue = [random.randint(0, (2**(typesize*8)-1)) for elem in range(0, var.elems)] else: myvalue = random.randint(0, (2**(typesize*8)-1)) if not var.array: if not isinstance(myvalue, list): value = myvalue else: LOG.warning( "Multiple initial values specified for a " "single element variable. Var: '%s'", var ) value = myvalue[0] values = [value] else: elems = var.size // typesize if not isinstance(myvalue, list): values = [myvalue] * elems else: values = (myvalue * ((len(myvalue) // elems) + 1))[ 0:elems] for idx, value in enumerate(values): if callable(value): value = value() if isinstance(value, float): values[idx] = ieee_float_to_int64(value) assert var.type in ["float", "double"] elif isinstance(value, six.integer_types): values[idx] = value else: raise MicroprobeCodeGenerationError( "Unable to initialize variable var: '%s' " "to value '%s'" % (myvalue, type(myvalue)) ) value_str = [str_fmt % value for value in values] value_str = "".join(value_str) value_str = ["0x%s" % value_str[i:i+2] for i in range(0, len(value_str), 2)] value_str = ".byte %s" % ",".join(value_str) astr = [] if False: if var.array(): value = var.value if var.value is not None: value = [0] valuestr = "" if not isinstance(value, list): value = [value] get_value = getnextf(itertools.cycle(value)) for dummy_idx in range(var.elems): value = get_value() if callable(value): value = value() valuestr = "%s%s," % (valuestr, value) else: value = var.value if var.value is not None: value = 0 valuestr = ".byte 0x%x" % value if section_address is not None: astr.append("# MICROPROBE LD @ %s 0x%X : { *(%s) } " % (section_name, section_address, section_name)) else: astr.append("# MICROPROBE LD @ %s : { *(%s) } " % (section_name, section_name)) astr.append(".section %s" % section_name) astr.append(".global %s" % var.name) astr.append("%s:" % var.name) astr.append("%s\n" % value_str) return "\n".join(astr)