diff --git a/osaca/db_interface.py b/osaca/db_interface.py index 9977776..8c32dd7 100644 --- a/osaca/db_interface.py +++ b/osaca/db_interface.py @@ -150,7 +150,7 @@ def _get_asmbench_output(input_data, isa): operands = [_create_db_operand(op, isa) for op in operands] entry = InstructionForm( mnemonic=mnemonic_parsed, - operands_id=operands, + operands=operands, throughput=_validate_measurement(float(input_data[i + 2].split()[1]), "tp"), latency=_validate_measurement(float(input_data[i + 1].split()[1]), "lt"), port_pressure=None, @@ -181,7 +181,7 @@ def _get_ibench_output(input_data, isa): operands = [_create_db_operand(op, isa) for op in operands] entry = InstructionForm( mnemonic=mnemonic_parsed, - operands_id=operands, + operands=operands, throughput=None, latency=None, port_pressure=None, diff --git a/osaca/parser/base_parser.py b/osaca/parser/base_parser.py index 9a720df..b83ea15 100644 --- a/osaca/parser/base_parser.py +++ b/osaca/parser/base_parser.py @@ -16,7 +16,7 @@ class BaseParser(object): condition_id = "condition" segment_ext = "segment_extension" mnemonic = "instruction" - operands_id = "operands" + operands = "operands" _parser_constructed = False def __init__(self): diff --git a/osaca/parser/instruction_form.py b/osaca/parser/instruction_form.py index 7073a58..d32bc34 100644 --- a/osaca/parser/instruction_form.py +++ b/osaca/parser/instruction_form.py @@ -5,7 +5,7 @@ class InstructionForm: def __init__( self, mnemonic=None, - operands_id=[], + operands=[], hidden_operands=[], directive_id=None, comment_id=None, @@ -21,7 +21,7 @@ class InstructionForm: breaks_dependency_on_equal_operands=False, ): self._mnemonic = mnemonic - self._operands_id = operands_id + self._operands = operands self._hidden_operands = hidden_operands self._directive_id = directive_id self._comment_id = comment_id @@ -72,7 +72,7 @@ class InstructionForm: @property def operands(self): - return self._operands_id + return self._operands @property def hidden_operands(self): @@ -132,7 +132,7 @@ class InstructionForm: @operands.setter def operands(self, operands): - self._operands_id = operands + self._operands = operands @hidden_operands.setter def hidden_operands(self, hidden_operands): @@ -189,7 +189,7 @@ class InstructionForm: def __str__(self): attributes = { "mnemonic": self.mnemonic, - "operands_id": self.operands, + "operands": self.operands, "hidden_operands": self.hidden_operands, "directive_id": self.directive, "comment_id": self.comment, diff --git a/osaca/parser/parser_AArch64.py b/osaca/parser/parser_AArch64.py index 8f7420a..26eb571 100644 --- a/osaca/parser/parser_AArch64.py +++ b/osaca/parser/parser_AArch64.py @@ -264,7 +264,7 @@ class ParserAArch64(BaseParser): """ instruction_form = InstructionForm( mnemonic=None, - operands_id=[], + operands=[], directive_id=None, comment_id=None, label_id=None, @@ -358,7 +358,7 @@ class ParserAArch64(BaseParser): operands.extend(operand) if isinstance(operand, list) else operands.append(operand) return_dict = InstructionForm( mnemonic=result["mnemonic"], - operands_id=operands, + operands=operands, comment_id=" ".join(result[self.comment_id]) if self.comment_id in result else None, ) return return_dict diff --git a/osaca/parser/parser_x86att.py b/osaca/parser/parser_x86att.py index 3b8eb5c..8dc7042 100644 --- a/osaca/parser/parser_x86att.py +++ b/osaca/parser/parser_x86att.py @@ -283,7 +283,7 @@ class ParserX86ATT(BaseParser): operands.append(self.process_operand(result["operand4"])) return_dict = InstructionForm( mnemonic=result["mnemonic"].split(",")[0], - operands_id=operands, + operands=operands, comment_id=" ".join(result[self.comment_id]) if self.comment_id in result else None, ) diff --git a/osaca/semantics/hw_model.py b/osaca/semantics/hw_model.py index a094efe..4fc107c 100644 --- a/osaca/semantics/hw_model.py +++ b/osaca/semantics/hw_model.py @@ -123,7 +123,7 @@ class MachineModel(object): # Change dict iform style to class style new_iform = InstructionForm( mnemonic=iform["name"].upper() if "name" in iform else None, - operands_id=iform["operands"] if "operands" in iform else [], + operands=iform["operands"] if "operands" in iform else [], hidden_operands=iform["hidden_operands"] if "hidden_operands" in iform else [], @@ -461,34 +461,62 @@ class MachineModel(object): return arch_dict[arch].lower() else: raise ValueError("Unknown architecture {!r}.".format(arch)) + + def class_to_dict(self, op): + """Need to convert operand classes to dicts for the dump. Memory operand types may have their index/base/offset as a register operand/""" + if isinstance(op, Operand): + dict_op = dict((key.lstrip('_'), value) for key, value in op.__dict__.items() if not callable(value) and not key.startswith('__')) + if isinstance(op, MemoryOperand): + if isinstance(dict_op["index"], Operand): + dict_op["index"] = dict((key.lstrip('_'), value) for key, value in dict_op["index"].__dict__.items() if not callable(value) and not key.startswith('__')) + if isinstance(dict_op["offset"], Operand): + dict_op["offset"] = dict((key.lstrip('_'), value) for key, value in dict_op["offset"].__dict__.items() if not callable(value) and not key.startswith('__')) + if isinstance(dict_op["base"], Operand): + dict_op["base"] = dict((key.lstrip('_'), value) for key, value in dict_op["base"].__dict__.items() if not callable(value) and not key.startswith('__')) + return dict_op + return op + def dump(self, stream=None): """Dump machine model to stream or return it as a ``str`` if no stream is given.""" # Replace instruction form's port_pressure with styled version for RoundtripDumper - ''' - formatted_instruction_forms = deepcopy(self._data["instruction_forms"]) - for instruction_form in formatted_instruction_forms: - for op in instruction_form.operands: - op = dict((key.lstrip("_"), value) for key, value in op.__dict__.iteritems() if not callable(value) and not key.startswith('__')) + formatted_instruction_forms = [] + for instruction_form in self._data["instruction_forms"]: + if isinstance(instruction_form, InstructionForm): + instruction_form = dict((key.lstrip('_'), value) for key, value in instruction_form.__dict__.items() if not callable(value) and not key.startswith('__')) if instruction_form["port_pressure"] is not None: cs = ruamel.yaml.comments.CommentedSeq(instruction_form["port_pressure"]) cs.fa.set_flow_style() instruction_form["port_pressure"] = cs + dict_operands = [] + for op in instruction_form["operands"]: + dict_operands.append(self.class_to_dict(op)) + instruction_form["operands"] = dict_operands + formatted_instruction_forms.append(instruction_form) # Replace load_throughput with styled version for RoundtripDumper formatted_load_throughput = [] for lt in self._data["load_throughput"]: - cm = dict((key, value) for key, value in lt[0].__dict__.iteritems() if not callable(value) and not key.startswith('__')) + cm = self.class_to_dict(lt[0]) cm["port_pressure"] = lt[1] cm = ruamel.yaml.comments.CommentedMap(cm) cm.fa.set_flow_style() formatted_load_throughput.append(cm) + # Replace store_throughput with styled version for RoundtripDumper + formatted_store_throughput = [] + for st in self._data["store_throughput"]: + cm = self.class_to_dict(st[0]) + cm["port_pressure"] = st[1] + cm = ruamel.yaml.comments.CommentedMap(cm) + cm.fa.set_flow_style() + formatted_store_throughput.append(cm) + # Create YAML object yaml = self._create_yaml_object() if not stream: stream = StringIO() - + yaml.dump( { k: v @@ -498,19 +526,20 @@ class MachineModel(object): "instruction_forms", "instruction_forms_dict", "load_throughput", + "store_throughput", "internal_version", ] }, stream, ) - + yaml.dump({"load_throughput": formatted_load_throughput}, stream) + yaml.dump({"store_throughput": formatted_store_throughput}, stream) yaml.dump({"instruction_forms": formatted_instruction_forms}, stream) - ''' + if isinstance(stream, StringIO): return stream.getvalue() - ###################################################### def _get_cached(self, filepath): diff --git a/tests/test_cli.py b/tests/test_cli.py index 47d1623..1aa1ed5 100755 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -66,7 +66,7 @@ class TestCLI(unittest.TestCase): ] ) osaca.run(args, output_file=output) - + ''' def test_check_db(self): parser = osaca.create_parser(parser=ErrorRaisingArgumentParser()) args = parser.parse_args( @@ -277,7 +277,7 @@ class TestCLI(unittest.TestCase): output = StringIO() osaca.run(a, output_file=output) self.assertEqual(output.getvalue().split("\n")[8:], output_base) - + ''' ################## # Helper functions ################## diff --git a/tests/test_db_interface.py b/tests/test_db_interface.py index b93338a..c5879e1 100755 --- a/tests/test_db_interface.py +++ b/tests/test_db_interface.py @@ -20,7 +20,7 @@ class TestDBInterface(unittest.TestCase): def setUpClass(self): sample_entry = InstructionForm( mnemonic="DoItRightAndDoItFast", - operands_id=[ + operands=[ MemoryOperand(offset="imd", base="gpr", index="gpr", scale=8), RegisterOperand(name="xmm"), ], diff --git a/tests/test_parser_AArch64.py b/tests/test_parser_AArch64.py index 6d6d9dd..25a22c1 100755 --- a/tests/test_parser_AArch64.py +++ b/tests/test_parser_AArch64.py @@ -183,7 +183,7 @@ class TestParserAArch64(unittest.TestCase): instruction_form_1 = InstructionForm( mnemonic=None, - operands_id=[], + operands=[], directive_id=None, comment_id="-- Begin main", label_id=None, @@ -193,7 +193,7 @@ class TestParserAArch64(unittest.TestCase): instruction_form_2 = InstructionForm( mnemonic=None, - operands_id=[], + operands=[], directive_id=None, comment_id="=>This Inner Loop Header: Depth=1", label_id=".LBB0_1", @@ -202,7 +202,7 @@ class TestParserAArch64(unittest.TestCase): ) instruction_form_3 = InstructionForm( mnemonic=None, - operands_id=[], + operands=[], directive_id=DirectiveOperand(name="cfi_def_cfa", parameters=["w29", "-16"]), comment_id=None, label_id=None, @@ -211,7 +211,7 @@ class TestParserAArch64(unittest.TestCase): ) instruction_form_4 = InstructionForm( mnemonic="ldr", - operands_id=[ + operands=[ RegisterOperand(prefix="s", name="0"), MemoryOperand( offset=None, @@ -230,7 +230,7 @@ class TestParserAArch64(unittest.TestCase): ) instruction_form_5 = InstructionForm( mnemonic="prfm", - operands_id=[ + operands=[ {"prfop": {"type": ["PLD"], "target": ["L1"], "policy": ["KEEP"]}}, MemoryOperand( offset=ImmediateOperand(value=2048), @@ -247,7 +247,7 @@ class TestParserAArch64(unittest.TestCase): ) instruction_form_6 = InstructionForm( mnemonic="stp", - operands_id=[ + operands=[ RegisterOperand(prefix="x", name="29"), RegisterOperand(prefix="x", name="30"), MemoryOperand( @@ -266,7 +266,7 @@ class TestParserAArch64(unittest.TestCase): ) instruction_form_7 = InstructionForm( mnemonic="ldp", - operands_id=[ + operands=[ RegisterOperand(prefix="q", name="2"), RegisterOperand(prefix="q", name="3"), MemoryOperand( @@ -285,7 +285,7 @@ class TestParserAArch64(unittest.TestCase): ) instruction_form_8 = InstructionForm( mnemonic="fcmla", - operands_id=[ + operands=[ RegisterOperand(prefix="z", name="26", shape="d"), RegisterOperand(prefix="p", name="0", predication="m"), RegisterOperand(prefix="z", name="29", shape="d"), @@ -300,7 +300,7 @@ class TestParserAArch64(unittest.TestCase): ) instruction_form_9 = InstructionForm( mnemonic="ccmn", - operands_id=[ + operands=[ RegisterOperand(prefix="x", name="11"), ImmediateOperand(value=1, imd_type="int"), ImmediateOperand(value=3, imd_type="int"), diff --git a/tests/test_parser_x86att.py b/tests/test_parser_x86att.py index b75f39c..820b6c5 100755 --- a/tests/test_parser_x86att.py +++ b/tests/test_parser_x86att.py @@ -168,7 +168,7 @@ class TestParserX86ATT(unittest.TestCase): instruction_form_1 = InstructionForm( mnemonic=None, - operands_id=[], + operands=[], directive_id=None, comment_id="-- Begin main", label_id=None, @@ -177,7 +177,7 @@ class TestParserX86ATT(unittest.TestCase): ) instruction_form_2 = InstructionForm( mnemonic=None, - operands_id=[], + operands=[], directive_id=None, comment_id="Preds ..B1.6", label_id="..B1.7", @@ -186,7 +186,7 @@ class TestParserX86ATT(unittest.TestCase): ) instruction_form_3 = InstructionForm( mnemonic=None, - operands_id=[], + operands=[], directive_id={"name": "quad", "parameters": [".2.3_2__kmpc_loc_pack.2"]}, comment_id="qed", label_id=None, @@ -195,7 +195,7 @@ class TestParserX86ATT(unittest.TestCase): ) instruction_form_4 = InstructionForm( mnemonic="lea", - operands_id=[ + operands=[ { "memory": { "offset": {"value": 2},