def __call__(self, building_block, target): """ :param building_block: :param target: """ addresses_set = [] context = building_block.context for bbl in building_block.cfg.bbls: for instr in bbl.instrs: # if not instr.hfp_exponent_overflow_exception: # continue if not instr.decimal: continue for memoperand in instr.memory_operands(): if memoperand.address is None: continue if memoperand.address in addresses_set: continue if memoperand.is_load: # Set a correct value in that address assert memoperand.length > 0 # Step4: store the content to the target instrs = target.store_decimal( memoperand.address, memoperand.length, self._value, context ) context.set_memory_value( MemoryValue( memoperand.address, self._value, memoperand.length ) ) addresses_set.append(memoperand.address) building_block.add_init(instrs)
def __init__(self, value=0): """ :param value: (Default value = 0) """ super(InitializeMemoryFloatPass, self).__init__() self._var = microprobe.code.var.VariableSingle("FP_INITVAL", "double", value="%.20f" % value) self._varaddress = Address(base_address=self._var) self._value = value self._memvalue = MemoryValue(self._varaddress, value, 8) self._description = "Initialize all the memory location accessed by" \ " binary floating point operations to value: '%s'"\ "." % (self._value)
def __call__(self, building_block, target): """ :param building_block: :param target: """ variable_to_declare = False addresses_set = [] context = building_block.context for bbl in building_block.cfg.bbls: for instr in bbl.instrs: # if not instr.hfp_exponent_overflow_exception: # continue is_float = False for operand in instr.operands(): if operand.type.float and operand.is_input: is_float = True if not is_float: continue for memoperand in instr.memory_operands(): if memoperand.address is None: continue if memoperand.address in addresses_set: continue if memoperand.is_load: if variable_to_declare is False: variable_to_declare = True reg2 = target.get_register_for_address_arithmetic( context) instrs = target.set_register( reg2, ieee_float_to_int64(self._value), context) building_block.add_init(instrs) context.set_register_value( reg2, ieee_float_to_int64(self._value)) context.add_reserved_registers([reg2]) reg1 = target.get_register_for_address_arithmetic( context) context.add_reserved_registers([reg1]) instrs = target.set_register_to_address( reg1, memoperand.address, context) context.set_register_value(reg1, memoperand.address) instrs += target.store_integer(reg2, memoperand.address, 64, context) context.set_memory_value( MemoryValue(memoperand.address, self._value, 8)) addresses_set.append(memoperand.address) building_block.add_init(instrs) LOG.debug("Instruction: %s: %s", instr.address, instr) LOG.debug("Address: %s", memoperand.address) if variable_to_declare: context.remove_reserved_registers([reg1, reg2])
def __call__(self, building_block, target): """ :param building_block: :param target: """ descriptors = {} context = building_block.context for bbl in building_block.cfg.bbls: for instr in bbl.instrs: if instr.switching == "None": if self._strict: raise MicroprobeCodeGenerationError( "No switching defined for '%s'" % instr ) LOG.warning("No switching defined for '%s'", instr) continue if instr.architecture_type not in descriptors: LOG.debug("Initializing switching for '%s'", instr) statuses = [] for status in instr.switching: statuses.append(status) status_idx = 0 repl_idx = 0 output_registers = [None] * self._replicate for idx in range(0, self._replicate): for operand in instr.operands(): if operand.is_output: assert output_registers[idx] is None if statuses[0][0] == "None": continue try: output_registers[idx] = \ [reg for reg in operand.type.values() if reg not in context.reserved_registers][0] except IndexError: LOG.critical( [reg for reg in operand.type.values() if reg not in context.reserved_registers]) LOG.critical(operand) LOG.critical(building_block.context.dump()) raise NotImplementedError context.add_reserved_registers( operand.type.access(output_registers[idx]) ) building_block.add_init( target.set_register( output_registers[idx], statuses[0][ 0 ], building_block.context ) ) building_block.context.set_register_value( output_registers[idx], statuses[0][0] ) LOG.debug( "Output register set to '%x'", statuses[0][0] ) LOG.debug("Output registers: %s", output_registers) LOG.debug("Statuses: %s", statuses) LOG.debug("Index: %d", status_idx) LOG.debug("Replication Index: %d", repl_idx) descriptors[instr.architecture_type] = \ (output_registers, status_idx, repl_idx, statuses * self._replicate, 1) else: output_registers, status_idx, repl_idx, statuses, count = \ descriptors[instr.architecture_type] descriptors[instr.architecture_type] = \ (output_registers, status_idx, repl_idx, statuses, count + 1) for key, values in descriptors.items(): output_registers, status_idx, repl_idx, statuses, count = values descriptors[key] = ( output_registers, status_idx, repl_idx, statuses, count ) LOG.debug("Setting up switching") for bbl in building_block.cfg.bbls: for instr in bbl.instrs: LOG.debug("Instruction: '%s'", instr) if instr.switching == "None": LOG.debug("No switching defined for '%s'", instr) continue if len( [ oper for oper in instr.operands() if oper.value is None ] ) == 0: LOG.debug( "Operands of the instructions already set '%s'", instr ) continue output_registers, status_idx, repl_idx, statuses, count = \ descriptors[instr.architecture_type] output_register = output_registers[repl_idx] if count == 0 and statuses[0][0] != "None": LOG.debug( "Skip last switch if not pair to maintain " "switching effects" ) LOG.debug("Current count: %s", count) LOG.critical( instr.architecture_type, count, repl_idx, status_idx, len(statuses) ) # TODO: add strict/not strict parameter exit(0) if output_register is not None: instr.add_allow_register(output_register) status = statuses[ repl_idx * (len(statuses) // self._replicate) + status_idx ] LOG.debug("Current descriptor:") LOG.debug("Output register: %s", output_register) LOG.debug("Statuses: %s", statuses) LOG.debug("Index: %d", status_idx) LOG.debug("Replication Index: %d", repl_idx) LOG.debug("Current status: %s", status) LOG.debug("Current count: %s", count) memoperand_idx = 0 memoperand_list = [ memop for memop in instr.memory_operands() if memop.address is not None ] operand_idx = 0 operand_list = [ oper for oper in instr.operands() if oper.value is None and oper.is_input and not oper.type.constant ] # if len(operand_list) == 0: # for oper in instr.operands(): # LOG.debug(oper) # raise MicroprobeCodeGenerationError( # "No operand to switch. All already set?" # ) LOG.debug("Switching instruction: %s", instr) LOG.debug("Operands to switch:") for oper in operand_list: LOG.debug(oper) for switch_input in status[1:]: LOG.debug("Init value to set: %s", switch_input) LOG.debug("Operand idx: %d", operand_idx) if switch_input == "None": # Nothing to do. Assume a register or immediate LOG.debug("Skip") operand_idx += 1 elif isinstance(switch_input, str) and \ switch_input.startswith("Mem:"): # Memory LOG.debug("Memory operand") memoperand = memoperand_list[memoperand_idx] address = memoperand.address required_value = switch_input.split(":")[1] LOG.debug("Raw required value %s", str(required_value)) if "_" in required_value: size = int(required_value.split("_")[1], 10) required_value = required_value.split("_")[0] prefix = "" if required_value.upper().startswith("0X"): prefix = "0x" required_value = required_value[2:] elif required_value.upper().startswith("0B"): prefix = "0b" required_value = required_value[2:] opsize = memoperand.length * 8 assert opsize % size == 0 mult = int(opsize / size) required_value = prefix + required_value * mult required_value = int(required_value, 0) else: required_value = int(required_value, 0) # we can modify a bit the address if we maintain the # same cache line # linesize = target.cache_hierarchy.data_linesize() memory_set = False # for displacement in range( # 0, linesize / 8, memoperand.length # ): for displacement in [0]: address = address + displacement memvalue = building_block.context.get_memory_value( address ) LOG.debug("Required value: 0x%x", required_value) LOG.debug("Target address: %s", address) LOG.debug("Current memory value: %s", memvalue) if memvalue is None: LOG.debug("Initialize memory contents") mycontext = target.wrapper.context() treg = target.scratch_registers[0] instrs = target.set_register( treg, required_value, mycontext ) areg = target.scratch_registers[1] instrs += target.set_register_to_address( areg, address, mycontext ) mycontext.set_register_value( areg, address ) reg0 = \ target.get_register_for_address_arithmetic( mycontext ) instrs += target.set_register( reg0, 0, mycontext ) mycontext.set_register_value( reg0, 0 ) instrs += target.store_integer( treg, address, memoperand.length * 8, mycontext ) building_block.add_init(instrs, prepend=True) building_block.context.set_memory_value( MemoryValue( address, required_value, memoperand.length ) ) # memoperand.set_address( # address, building_block.context # ) LOG.debug("Memory contents initialized") memory_set = True break elif memvalue.value == required_value and \ memvalue.length == memoperand.length: # perfect, nothing to do LOG.debug( "Memory contents already contain the" " required value." ) # memoperand.set_address( # address, building_block.context # ) memory_set = True break if memory_set is False: LOG.warning( "Unable to set the memory to the" " required value." ) memoperand_idx += 1 else: operand = operand_list[operand_idx] LOG.debug("Operand: %s", operand) if isinstance(switch_input, str): LOG.debug( "Required value before: %s", switch_input ) if "_" in switch_input: size = int(switch_input.split("_")[1], 10) switch_input = switch_input.split("_")[0] prefix = "" if switch_input.upper().startswith("0X"): prefix = "0x" switch_input = switch_input[2:] elif switch_input.upper().startswith("0B"): prefix = "0b" switch_input = switch_input[2:] if operand.type.immediate: raise MicroprobeCodeGenerationError( "No support for immediate definition " "with '_'. Provide the full value." ) else: opsize = \ operand.type.random_value().type.size assert opsize % size == 0 mult = int(opsize / size) switch_input = prefix + switch_input * mult switch_input = int(switch_input, 0) LOG.debug("Required value: %s", switch_input) if operand.is_output: LOG.debug( "Operand is output. Already fixed to " "'%s' ", output_register ) operand.set_value(output_register) elif operand.type.immediate: LOG.debug( "Operand is immediate. Set to '%s' (0x%X)", switch_input, switch_input ) operand.set_value(switch_input) elif building_block.context.register_has_value( switch_input ) and building_block.context.registers_get_value( switch_input )[0] in operand.type.values(): treg = building_block.context.registers_get_value( switch_input )[0] LOG.debug("Value already in register '%s'", treg) operand.set_value(treg) else: LOG.debug("Initializing register contents") tregs = [ reg for reg in operand.type.values() if reg not in context.reserved_registers ] if len(tregs) == 0: # raise MicroprobeCodeGenerationError( # "No free registers available to switching" # ) LOG.debug( "No free registers available to switching" ) else: treg = tregs[0] instrs = target.set_register( treg, switch_input, context ) operand.set_value(treg) building_block.add_init(instrs) building_block.context.set_register_value( treg, switch_input ) building_block.context.add_reserved_registers( [reg for reg in operand.uses() if reg not in context.reserved_registers] ) LOG.debug( "Register '%s' set to '%s'", treg, switch_input ) operand_idx += 1 repl_idx += 1 repl_idx = repl_idx % self._replicate if repl_idx == 0: status_idx += 1 status_idx = status_idx % ( len(statuses) // self._replicate) descriptors[instr.architecture_type] = \ (output_registers, status_idx, repl_idx, statuses, count - 1)
def __call__(self, building_block, target): """ :param building_block: :param target: """ descriptors = {} context = building_block.context for bbl in building_block.cfg.bbls: for instr in bbl.instrs: if instr.switching == "None": if self._strict: raise MicroprobeCodeGenerationError( "No switching defined for '%s'" % instr) LOG.warning("No switching defined for '%s'", instr) continue if instr.architecture_type not in descriptors: LOG.debug("Initializing switching for '%s'", instr) statuses = [] for status in instr.switching: statuses.append(status) status_idx = 0 repl_idx = 0 output_registers = [None] * self._replicate for idx in range(0, self._replicate): for operand in instr.operands(): if operand.is_output: assert output_registers[idx] is None if statuses[0][0] == "None": continue try: output_registers[idx] = \ [reg for reg in operand.type.values() if reg not in context.reserved_registers][0] except IndexError: LOG.critical([ reg for reg in operand.type.values() if reg not in context.reserved_registers ]) LOG.critical(operand) LOG.critical(building_block.context.dump()) raise NotImplementedError context.add_reserved_registers( [output_registers[idx]]) building_block.add_init( target.set_register( output_registers[idx], statuses[0][0], building_block.context)) building_block.context.set_register_value( output_registers[idx], statuses[0][0]) LOG.debug("Output register set to '%x'", statuses[0][0]) LOG.debug("Output registers: %s", output_registers) LOG.debug("Statuses: %s", statuses) LOG.debug("Index: %d", status_idx) LOG.debug("Replication Index: %d", repl_idx) descriptors[instr.architecture_type] = \ (output_registers, status_idx, repl_idx, statuses * self._replicate, 1) else: output_registers, status_idx, repl_idx, statuses, count = \ descriptors[instr.architecture_type] descriptors[instr.architecture_type] = \ (output_registers, status_idx, repl_idx, statuses, count + 1) for key, values in descriptors.items(): output_registers, status_idx, repl_idx, statuses, count = values descriptors[key] = (output_registers, status_idx, repl_idx, statuses, count) LOG.debug("Setting up switching") for bbl in building_block.cfg.bbls: for instr in bbl.instrs: LOG.debug("Instruction: '%s'", instr) if instr.switching == "None": LOG.debug("No switching defined for '%s'", instr) continue if len([ oper for oper in instr.operands() if oper.value is None ]) == 0: LOG.debug("Operands of the instructions already set '%s'", instr) continue output_registers, status_idx, repl_idx, statuses, count = \ descriptors[instr.architecture_type] output_register = output_registers[repl_idx] if count == 0 and statuses[0][0] != "None": LOG.debug("Skip last switch if not pair to maintain " "switching effects") LOG.debug("Current count: %s", count) LOG.critical(instr.architecture_type, count, repl_idx, status_idx, len(statuses)) # TODO: add strict/not strict parameter exit(0) if output_register is not None: instr.add_allow_register(output_register) status = statuses[repl_idx * (len(statuses) // self._replicate) + status_idx] LOG.debug("Current descriptor:") LOG.debug("Output register: %s", output_register) LOG.debug("Statuses: %s", statuses) LOG.debug("Index: %d", status_idx) LOG.debug("Replication Index: %d", repl_idx) LOG.debug("Current status: %s", status) LOG.debug("Current count: %s", count) memoperand_idx = 0 memoperand_list = [ memop for memop in instr.memory_operands() if memop.address is not None ] operand_idx = 0 operand_list = [ oper for oper in instr.operands() if oper.value is None and oper.is_input and not oper.type.constant ] for switch_input in status[1:]: LOG.debug("Init: %s", switch_input) if switch_input == "None": # Nothing to do. Assume a register or immediate operand_idx += 1 elif isinstance(switch_input, str) and \ switch_input.startswith("Mem:"): # Memory required_value = int(switch_input.split(":")[1], 0) memoperand = memoperand_list[memoperand_idx] address = memoperand.address # we can modify a bit the address if we maintain the # same cache line # linesize = target.cache_hierarchy.data_linesize() memory_set = False # for displacement in range( # 0, linesize / 8, memoperand.length # ): for displacement in [0]: address = address + displacement memvalue = building_block.context.get_memory_value( address) LOG.debug("Required value: 0x%x", required_value) LOG.debug("Target address: %s", address) LOG.debug("Current memory value: %s", memvalue) if memvalue is None: LOG.debug("Initialize memory contents") treg = target.scratch_registers[0] instrs = target.set_register( treg, required_value, building_block.context) instrs += target.store_integer( treg, address, memoperand.length * 8, building_block.context) building_block.add_init(instrs) building_block.context.set_memory_value( MemoryValue(address, required_value, memoperand.length)) memoperand.set_address(address, building_block.context) LOG.debug("Memory contents initialized") memory_set = True break elif memvalue.value == required_value and \ memvalue.length == memoperand.length: # perfect, nothing to do LOG.debug("Memory contents already contain the" " required value.") memoperand.set_address(address, building_block.context) memory_set = True break if memory_set is False: LOG.warning("Unable to set the memory to the" " required value.") memoperand_idx += 1 else: LOG.debug("Required value: %s", switch_input) operand = operand_list[operand_idx] LOG.debug("Operand: %s", operand) if operand.is_output: LOG.debug( "Operand is output. Already fixed to " "'%s' ", output_register) operand.set_value(output_register) elif operand.type.immediate: LOG.debug("Operand is immediate. Set to '%s'", switch_input) operand.set_value(switch_input) elif building_block.context.register_has_value( switch_input): treg = building_block.context.registers_get_value( switch_input)[0] LOG.debug("Value already in register '%s'", treg) operand.set_value(treg) else: LOG.debug("Initializing register contents") treg = [ reg for reg in operand.type.values() if reg not in context.reserved_registers ][0] instrs = target.set_register( treg, switch_input, context) operand.set_value(treg) building_block.add_init(instrs) building_block.context.set_register_value( treg, switch_input) building_block.context.add_reserved_registers( [treg]) LOG.debug("Register '%s' set to '%s'", treg, switch_input) operand_idx += 1 repl_idx += 1 repl_idx = repl_idx % self._replicate if repl_idx == 0: status_idx += 1 status_idx = status_idx % (len(statuses) // self._replicate) descriptors[instr.architecture_type] = \ (output_registers, status_idx, repl_idx, statuses, count - 1)