def merge_value(self, opr): if self.width != opr.width: raise BuilderException( "Changing operand \"%s\" but width don't match: %d and %d." % (opr.name, self.width, opr.width)) if self.type != opr.type: raise BuilderException( "Changing operand \"%s\" but type don't match: %s and %s." % (opr.name, self.type, opr.type)) self.value = merge_imm_value(self.value, opr.value)
def split_operand(self): split_const = copy.deepcopy(self) bit_list = bit_string_to_list(self.bits) if len(bit_list) != self.width: raise BuilderException( "Expecting bit list to be the same size as operand width.") const_bit_list = list() const_value = "" variable_bit_list = list() for i in range(self.width): if self.value[i] == "x": variable_bit_list.append(bit_list[i]) else: const_bit_list.append(bit_list[i]) const_value += self.value[i] self.bits = bit_list_to_string(variable_bit_list) self.width = len(variable_bit_list) self.value = None split_const.bits = bit_list_to_string(const_bit_list) split_const.width = len(const_bit_list) split_const.value = const_value split_const.update_type() return split_const
def add_instruction(self, instr): # If we try to add more instructions than we can handle, just raise an # exception if (len(self.instructions) + 1) > self.size: raise BuilderException( 'Adding instruction "%s" to full group "%s\, with size "%d".' % (instr.name, self.name, self.size)) # If there's still space, append the instruction to the end of the list self.instructions.append(instr)
def find_operand(self, name, fail_not_found=True): for opr in self.operands: if opr.name == name: return opr if fail_not_found: raise BuilderException( "Operand \"%s\" not found in instruction \"%s\"." % (name, self.get_full_ID())) else: return None
def change_operand(self, opr, update_const=False): if opr.type == "Constant": existing_opr = self.find_operand(opr.name) if existing_opr.width != opr.width: raise BuilderException( 'Changing operand "%s" but width don\'t match: %d and %d.' % (opr.name, existing_opr.width, opr.width)) self.operands.remove(existing_opr) self.constOp.merge_operand(opr) elif opr.type in ["Immediate", "Choices"]: existing_opr = self.find_operand(opr.name) if existing_opr.value and existing_opr.value.find("!=") == 0: print( "WARNING: need special handling of this instruction with " 'constraint "%s" on operand "%s".' % (existing_opr.value, opr.name)) return existing_opr.merge_value(opr) existing_opr.update_type() if existing_opr.type != "Constant": # print ("Spliting operand \"%s\"" % opr.name) split_const = existing_opr.split_operand() self.constOp.merge_operand(split_const) else: self.operands.remove(existing_opr) self.constOp.merge_operand(existing_opr) elif opr.type == "Register": if opr.value == ("N" * opr.width): # the value field is a series of "N"s pass else: raise BuilderException( "Unexpected change_operand on Register type with " 'value="%s".' % (opr.value)) else: raise BuilderException('Unexpected change_operand type "%s".' % (opr.type)) if update_const: self.update_constant()
def find_operand(self, name, fail_not_found=True): for opr in self.operands: if opr.name == name: return opr if name == "const_bits" and self.constOp and self.constOp.name == name: return self.constOp if fail_not_found: raise BuilderException( 'Operand "%s" not found in instruction "%s".' % (name, self.get_full_ID()) ) else: return None
def rename_op(self, old_name, new_name, multiple=False): found_any = False for i in range(len(self.ops)): if self.ops[i] == old_name: self.ops[i] = new_name if not multiple: break else: found_any = True else: if not found_any: raise BuilderException( "Asm.rename_op: old op \"%s\" not found, ops are: %s." % (old_name, self.show_ops()))
def set_constatnt_bit(self, bit_loc, bit_value): if (self.value is None) or (len(self.value) == 0): self.value = "x" * self.width if bit_loc >= self.width: raise BuilderException( "set_constatnt_bit: bit location %d larger than operand width %d" % (bit_loc, self.width)) new_value = "" str_loc = self.width - bit_loc - 1 for i in range(len(self.value)): if i == str_loc: new_value += bit_value else: new_value += self.value[i] self.value = new_value
def merge_operand(self, opr, update_bits=False): if self.type != opr.type: raise BuilderException( "Merging different types of operand \"%s\"=>\"%s\" and \"%s\"=>\"%s\"." % (self.name, self.type, opr.name, opr.type)) self.bits += "," + opr.bits if self.value: self.value += opr.value else: self.value = opr.value self.width += opr.width if update_bits: self.bits = update_bits(self.bits)
def merge_operand(self, opr, a_update_bits=False): if self.type != opr.type: raise BuilderException( 'Merging different types of operand "%s"=>"%s" and "%s"=>"%s".' % (self.name, self.type, opr.name, opr.type)) self.bits += "," + opr.bits if self.value: self.value += opr.value else: self.value = opr.value self.width += opr.width if a_update_bits: self.bits = a_update_bits(self.bits)
def merge_imm_value(value1, value2): if None is value1: return value2 if len(value1) != len(value2): raise BuilderException( "Merging value but value length don't match: %d and %d." % (len(value1), len(value2))) merged_value = "" for i in range(len(value1)): if value1[i] == "x": merged_value += value2[i] else: merged_value += value1[i] return merged_value
def merge_imm_value(value1, value2): if None == value1: return value2 if len(value1) != len(value2): raise BuilderException( "Merging value but value length don't match: %d and %d." % (len(value1), len(value2))) merged_value = "" for i in range(len(value1)): if value1[i] == "x": merged_value += value2[i] else: merged_value += value1[i] # print ("Merged value1 \"%s\" and value2 \"%s\" into \"%s\"" % (value1, value2, merged_value)) return merged_value
def search_operand(self, name, fail_not_found=True): for opr in self.operands: if opr.name == name: return opr if name == "const_bits" and self.constOp and self.constOp.name == name: return self.constOp if isinstance(opr, GroupOperand): opr_tmp = opr.find_operand(name, False) if opr_tmp is None: continue else: return opr_tmp if fail_not_found: raise BuilderException( "Operand \"%s\" not found in instruction \"%s\"." % (name, self.get_full_ID())) else: return None
def add_instruction(self, instr, instr_format): if instr_format != self.name: raise BuilderException( "Adding instruction \"%s\" with format \"%s\" to group \"%s\"." % (instr.name, instr_format, self.name)) self.instructions.append(instr)
def add_instruction(self, instr, instr_format): if instr_format != self.name: raise BuilderException( 'Adding instruction "%s" with format "%s" to group "%s".' % (instr.name, instr_format, self.name)) self.instructions.append(instr)
def add_instruction(self, instr): if instr.name != self.name: raise BuilderException( "Adding instruction \"%s\" to group \"%s\"." % (instr.name, self.name)) self.instructions.append(instr)
def add_instruction(self, instr): if instr.name != self.name: raise BuilderException('Adding instruction "%s" to group "%s".' % (instr.name, self.name)) self.instructions.append(instr)