From 841a4a5724a9deef00551644988c710dc1d5cd65 Mon Sep 17 00:00:00 2001 From: JanLJL Date: Thu, 2 Mar 2023 15:50:13 +0100 Subject: [PATCH 1/7] resolve #81 --- osaca/data/a64fx.yml | 98 +++++++++++++++++++++++++++----------- osaca/data/isa/aarch64.yml | 49 ++++++++++++++++++- 2 files changed, 117 insertions(+), 30 deletions(-) diff --git a/osaca/data/a64fx.yml b/osaca/data/a64fx.yml index 4560e84..150b592 100644 --- a/osaca/data/a64fx.yml +++ b/osaca/data/a64fx.yml @@ -734,7 +734,24 @@ instruction_forms: throughput: 43.0 latency: 43.0 # 1*p0+43*p0DV port_pressure: [[1, '0'], [43.0, [0DV]]] -- name: [fmad, fmla] +- name: [fmad, fmla, mla] + operands: + - class: register + prefix: z + shape: d + width: '*' + - class: register + prefix: z + shape: d + width: '*' + - class: register + prefix: z + shape: d + width: '*' + throughput: 0.5 + latency: 9.0 # 1*p02 + port_pressure: [[1, '02']] +- name: [fmad, fmla, mla, fmsb, fmls, mls] operands: - class: register prefix: z @@ -754,7 +771,7 @@ instruction_forms: throughput: 0.5 latency: 9.0 # 1*p02 port_pressure: [[1, '02']] -- name: [fmad, fmla] +- name: [fmad, fmla, fmsb, fmls] operands: - class: register prefix: z @@ -776,36 +793,19 @@ instruction_forms: throughput: 0.5 latency: 9.0 # 1*p02 port_pressure: [[1, '02']] -- name: [fmla, fmls] +- name: [fmla, fmls, mla, mls] operands: - class: register prefix: v - shape: s + shape: '*' width: '*' - class: register prefix: v - shape: s + shape: '*' width: '*' - class: register prefix: v - shape: s - width: '*' - throughput: 0.5 - latency: 9.0 # 1*p02 - port_pressure: [[1, '02']] -- name: [fmla, fmls] - operands: - - class: register - prefix: v - shape: d - width: '*' - - class: register - prefix: v - shape: d - width: '*' - - class: register - prefix: v - shape: d + shape: '*' width: '*' throughput: 0.5 latency: 9.0 # 1*p02 @@ -2546,8 +2546,50 @@ instruction_forms: throughput: 1.0 latency: 6.0 port_pressure: [[1, '2']] - - - - - +- name: [sadalp, uadalp] + operands: + - class: register + prefix: v + shape: '*' + width: '*' + - class: register + prefix: v + shape: '*' + width: '*' + throughput: 3.0 + latency: 14.0 + port_pressure: [[3, '2']] +- name: [smlal, smlal2] + operands: + - class: register + prefix: v + shape: s + width: '*' + - class: register + prefix: v + shape: '*' + width: '*' + - class: register + prefix: v + shape: '*' + width: '*' + throughput: 8.0 + latency: 18.0 + port_pressure: {0: [[8, '0']], 1: [[8, '2']]} +- name: [smlal, smlal2] + operands: + - class: register + prefix: v + shape: d + width: '*' + - class: register + prefix: v + shape: '*' + width: '*' + - class: register + prefix: v + shape: '*' + width: '*' + throughput: 3.0 + latency: 15.0 + port_pressure: {0: [[3, '0']], 1: [[3, '2']]} diff --git a/osaca/data/isa/aarch64.yml b/osaca/data/isa/aarch64.yml index 85246ea..0651747 100644 --- a/osaca/data/isa/aarch64.yml +++ b/osaca/data/isa/aarch64.yml @@ -62,7 +62,7 @@ instruction_forms: imd: int source: false destination: false - - name: fmla + - name: [fmla, fmad, mla, fmls, fmsb, mls] operands: - class: register prefix: "*" @@ -84,7 +84,7 @@ instruction_forms: shape: "*" source: true destination: false - - name: fmla + - name: [fmla, mla, fmls, mls, smlal, smlal2, smlalb, smlalt, smlsl, smlsl2, smlslb, smlslt, umlal, umlal2, umlalb, umlalt, umlsl, umlsl2, umlslb, umlslt] operands: - class: register prefix: "*" @@ -101,6 +101,51 @@ instruction_forms: shape: "*" source: true destination: false + - name: [sadalp, uadalp] + operands: + - class: register + prefix: "*" + shape: "*" + source: true + destination: true + - class: register + prefix: "*" + shape: "*" + source: true + destination: false + - name: [sadalp, uadalp, sabal, sabal2, sabalb, sabalt] + operands: + - class: register + prefix: "*" + shape: "*" + source: true + destination: true + - class: register + prefix: "*" + shape: "*" + source: true + destination: false + - class: register + prefix: "*" + shape: "*" + source: true + destination: false + - name: [ssra, srsra, usra, ursra] + operands: + - class: register + prefix: "*" + shape: "*" + source: true + destination: true + - class: register + prefix: "*" + shape: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false - name: ldp operands: - class: register From dbfba9ce5b93aa3f35f4472af0ff3e5605af0de8 Mon Sep 17 00:00:00 2001 From: JanLJL Date: Fri, 3 Mar 2023 14:39:28 +0100 Subject: [PATCH 2/7] added another instruction --- osaca/data/a64fx.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/osaca/data/a64fx.yml b/osaca/data/a64fx.yml index 150b592..3775b8d 100644 --- a/osaca/data/a64fx.yml +++ b/osaca/data/a64fx.yml @@ -1915,15 +1915,26 @@ instruction_forms: operands: - class: register prefix: v - shape: b + shape: '*' width: '*' - class: register prefix: v - shape: b + shape: '*' width: '*' throughput: 0.5 latency: 4.0 # 1*p02 port_pressure: [[1, '02']] +- name: mov + operands: + - class: register + prefix: '*' + - class: register + prefix: v + shape: '*' + width: '*' + throughput: 3.0 + latency: 15.0 # 3*p0+3*p3 + port_pressure: [[3, '0'], [3, '3']] - name: movprfx operands: - class: register From 2884d17971f29533c4aa2d419ffda3c897af5228 Mon Sep 17 00:00:00 2001 From: JanLJL Date: Fri, 3 Mar 2023 14:41:48 +0100 Subject: [PATCH 3/7] enabled indexing without shape and lane for vector regs --- osaca/parser/parser_AArch64.py | 17 +++++++---------- tests/test_parser_AArch64.py | 10 ++++++++++ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/osaca/parser/parser_AArch64.py b/osaca/parser/parser_AArch64.py index 4cf8c78..a572c94 100755 --- a/osaca/parser/parser_AArch64.py +++ b/osaca/parser/parser_AArch64.py @@ -132,8 +132,8 @@ class ParserAArch64(BaseParser): pp.Literal(".") + pp.Optional(pp.Word("12468")).setResultsName("lanes") + pp.Word(pp.alphas, exact=1).setResultsName("shape") - + pp.Optional(index) ) + + pp.Optional(index) ) predicate = ( pp.CaselessLiteral("p").setResultsName("prefix") @@ -510,15 +510,12 @@ class ParserAArch64(BaseParser): def get_full_reg_name(self, register): """Return one register name string including all attributes""" - if "lanes" in register: - return ( - register["prefix"] - + str(register["name"]) - + "." - + str(register["lanes"]) - + register["shape"] - ) - return register["prefix"] + str(register["name"]) + name = register["prefix"] + str(register["name"]) + if "shape" in register: + name += "." + str(register.get("lanes", "")) + register["shape"] + if "index" in register: + name += "[" + register["index"] + "]" + return name def normalize_imd(self, imd): """Normalize immediate to decimal based representation""" diff --git a/tests/test_parser_AArch64.py b/tests/test_parser_AArch64.py index fdcf7f1..053aca1 100755 --- a/tests/test_parser_AArch64.py +++ b/tests/test_parser_AArch64.py @@ -81,6 +81,7 @@ class TestParserAArch64(unittest.TestCase): instr5 = "ldr x0, [x0, #:got_lo12:q2c]" instr6 = "adrp x0, :got:visited" instr7 = "fadd v17.2d, v16.2d, v1.2d" + instr8 = "mov.d x0, v16.d[1]" parsed_1 = self.parser.parse_instruction(instr1) parsed_2 = self.parser.parse_instruction(instr2) @@ -89,6 +90,7 @@ class TestParserAArch64(unittest.TestCase): parsed_5 = self.parser.parse_instruction(instr5) parsed_6 = self.parser.parse_instruction(instr6) parsed_7 = self.parser.parse_instruction(instr7) + parsed_8 = self.parser.parse_instruction(instr8) self.assertEqual(parsed_1.instruction, "vcvt.F32.S32") self.assertEqual(parsed_1.operands[0].register.name, "1") @@ -142,6 +144,14 @@ class TestParserAArch64(unittest.TestCase): self.assertEqual(parsed_7.operands[0].register.shape, "d") self.assertEqual(self.parser.get_full_reg_name(parsed_7.operands[2].register), "v1.2d") + self.assertEqual(parsed_8.instruction, "mov.d") + self.assertEqual(parsed_8.operands[0].register.name, "0") + self.assertEqual(parsed_8.operands[0].register.prefix, "x") + self.assertEqual(parsed_8.operands[1].register.name, "16") + self.assertEqual(parsed_8.operands[1].register.prefix, "v") + self.assertEqual(parsed_8.operands[1].register.index, "1") + self.assertEqual(self.parser.get_full_reg_name(parsed_8.operands[1].register), "v16.d[1]") + def test_parse_line(self): line_comment = "// -- Begin main" line_label = ".LBB0_1: // =>This Inner Loop Header: Depth=1" From 9f715c0ba36ba452014405db0c2fe70ecc8cfd01 Mon Sep 17 00:00:00 2001 From: JanLJL Date: Fri, 3 Mar 2023 15:11:40 +0100 Subject: [PATCH 4/7] added fallback search in arch/ISA model for ARM instructions with shape/cc suffixes --- osaca/semantics/arch_semantics.py | 27 ++++++++++++++++++- osaca/semantics/isa_semantics.py | 43 +++++++++++++++++++++++++++++-- tests/test_semantics.py | 4 +++ 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/osaca/semantics/arch_semantics.py b/osaca/semantics/arch_semantics.py index 10b3a97..e37a674 100755 --- a/osaca/semantics/arch_semantics.py +++ b/osaca/semantics/arch_semantics.py @@ -192,11 +192,25 @@ class ArchSemantics(ISASemantics): instruction_data = self._machine_model.get_instruction( instruction_form["instruction"], instruction_form["operands"] ) - if not instruction_data and instruction_form["instruction"][-1] in self.GAS_SUFFIXES: + if ( + not instruction_data + and self._isa == "x86" + and instruction_form["instruction"][-1] in self.GAS_SUFFIXES + ): # check for instruction without GAS suffix instruction_data = self._machine_model.get_instruction( instruction_form["instruction"][:-1], instruction_form["operands"] ) + if ( + instruction_data is None + and self._isa == "aarch64" + and "." in instruction_form["instruction"] + ): + # Check for instruction without shape/cc suffix + suffix_start = instruction_form["instruction"].index(".") + instruction_data = self._machine_model.get_instruction( + instruction_form["instruction"][:suffix_start], instruction_form["operands"] + ) if instruction_data: # instruction form in DB ( @@ -223,12 +237,23 @@ class ArchSemantics(ISASemantics): ) if ( not instruction_data_reg + and self._isa == "x86" and instruction_form["instruction"][-1] in self.GAS_SUFFIXES ): # check for instruction without GAS suffix instruction_data_reg = self._machine_model.get_instruction( instruction_form["instruction"][:-1], operands ) + if ( + instruction_data_reg is None + and self._isa == "aarch64" + and "." in instruction_form["instruction"] + ): + # Check for instruction without shape/cc suffix + suffix_start = instruction_form["instruction"].index(".") + instruction_data_reg = self._machine_model.get_instruction( + instruction_form["instruction"][:suffix_start], operands + ) if instruction_data_reg: assign_unknown = False reg_type = self._parser.get_reg_type( diff --git a/osaca/semantics/isa_semantics.py b/osaca/semantics/isa_semantics.py index fca5955..15b6a49 100755 --- a/osaca/semantics/isa_semantics.py +++ b/osaca/semantics/isa_semantics.py @@ -55,11 +55,25 @@ class ISASemantics(object): isa_data = self._isa_model.get_instruction( instruction_form["instruction"], instruction_form["operands"] ) - if isa_data is None and instruction_form["instruction"][-1] in self.GAS_SUFFIXES: + if ( + isa_data is None + and self._isa == "x86" + and instruction_form["instruction"][-1] in self.GAS_SUFFIXES + ): # Check for instruction without GAS suffix isa_data = self._isa_model.get_instruction( instruction_form["instruction"][:-1], instruction_form["operands"] ) + if ( + isa_data is None + and self._isa == "aarch64" + and "." in instruction_form["instruction"] + ): + # Check for instruction without shape/cc suffix + suffix_start = instruction_form["instruction"].index(".") + isa_data = self._isa_model.get_instruction( + instruction_form["instruction"][:suffix_start], instruction_form["operands"] + ) operands = instruction_form["operands"] op_dict = {} assign_default = False @@ -77,12 +91,23 @@ class ISASemantics(object): ) if ( isa_data_reg is None + and self._isa == "x86" and instruction_form["instruction"][-1] in self.GAS_SUFFIXES ): # Check for instruction without GAS suffix isa_data_reg = self._isa_model.get_instruction( instruction_form["instruction"][:-1], operands_reg ) + if ( + isa_data_reg is None + and self._isa == "aarch64" + and "." in instruction_form["instruction"] + ): + # Check for instruction without shape/cc suffix + suffix_start = instruction_form["instruction"].index(".") + isa_data_reg = self._isa_model.get_instruction( + instruction_form["instruction"][:suffix_start], operands_reg + ) if isa_data_reg: assign_default = False op_dict = self._apply_found_ISA_data(isa_data_reg, operands) @@ -159,11 +184,25 @@ class ISASemantics(object): isa_data = self._isa_model.get_instruction( instruction_form["instruction"], instruction_form["operands"] ) - if isa_data is None and instruction_form["instruction"][-1] in self.GAS_SUFFIXES: + if ( + isa_data is None + and self._isa == "x86" + and instruction_form["instruction"][-1] in self.GAS_SUFFIXES + ): # Check for instruction without GAS suffix isa_data = self._isa_model.get_instruction( instruction_form["instruction"][:-1], instruction_form["operands"] ) + if ( + isa_data is None + and self._isa == "aarch64" + and "." in instruction_form["instruction"] + ): + # Check for instruction without shape/cc suffix + suffix_start = instruction_form["instruction"].index(".") + isa_data = self._isa_model.get_instruction( + instruction_form["instruction"][:suffix_start], instruction_form["operands"] + ) if only_postindexed: for o in instruction_form.operands: diff --git a/tests/test_semantics.py b/tests/test_semantics.py index 327f173..35daf47 100755 --- a/tests/test_semantics.py +++ b/tests/test_semantics.py @@ -159,6 +159,10 @@ class TestSemanticTools(unittest.TestCase): test_mm_arm.get_instruction("b.ne", [{"class": "identifier"}]), test_mm_arm.get_instruction("b.ne", [{"class": "identifier"}]), ) + self.assertEqual( + test_mm_arm.get_instruction("b.someNameThatDoesNotExist", [{"class": "identifier"}]), + test_mm_arm.get_instruction("b.someOtherName", [{"class": "identifier"}]), + ) # test full instruction name self.assertEqual( From f06f767c3422493569323bb2844c9faffb77e0cb Mon Sep 17 00:00:00 2001 From: JanLJL Date: Fri, 3 Mar 2023 15:24:18 +0100 Subject: [PATCH 5/7] formatting according to black --- osaca/semantics/isa_semantics.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/osaca/semantics/isa_semantics.py b/osaca/semantics/isa_semantics.py index 15b6a49..b5a1d9a 100755 --- a/osaca/semantics/isa_semantics.py +++ b/osaca/semantics/isa_semantics.py @@ -64,11 +64,7 @@ class ISASemantics(object): isa_data = self._isa_model.get_instruction( instruction_form["instruction"][:-1], instruction_form["operands"] ) - if ( - isa_data is None - and self._isa == "aarch64" - and "." in instruction_form["instruction"] - ): + if isa_data is None and self._isa == "aarch64" and "." in instruction_form["instruction"]: # Check for instruction without shape/cc suffix suffix_start = instruction_form["instruction"].index(".") isa_data = self._isa_model.get_instruction( @@ -193,11 +189,7 @@ class ISASemantics(object): isa_data = self._isa_model.get_instruction( instruction_form["instruction"][:-1], instruction_form["operands"] ) - if ( - isa_data is None - and self._isa == "aarch64" - and "." in instruction_form["instruction"] - ): + if isa_data is None and self._isa == "aarch64" and "." in instruction_form["instruction"]: # Check for instruction without shape/cc suffix suffix_start = instruction_form["instruction"].index(".") isa_data = self._isa_model.get_instruction( From 10d4c4b87e27118539b97c7798a153c91c32c964 Mon Sep 17 00:00:00 2001 From: JanLJL Date: Tue, 7 Mar 2023 17:04:32 +0100 Subject: [PATCH 6/7] added instruction --- osaca/data/a64fx.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/osaca/data/a64fx.yml b/osaca/data/a64fx.yml index 3775b8d..d1e89a7 100644 --- a/osaca/data/a64fx.yml +++ b/osaca/data/a64fx.yml @@ -2265,6 +2265,20 @@ instruction_forms: throughput: 1.0 latency: 0 # 1*p56+1*p0 port_pressure: [[1, '5'], [1,'6'], [1, '0']] +- name: str + operands: + - class: register + prefix: d + - class: memory + base: x + offset: '*' + index: '*' + scale: '*' + pre-indexed: true + post-indexed: false + throughput: 1.0 + latency: 0 # 1*p56+1*p0+1*p0234 + port_pressure: [[1, '5'], [1,'6'], [1, '0'], [1, '0234']] - name: str operands: - class: register From 7e6eb7ce58e2e5a346e5c27e8d9a6a5155640724 Mon Sep 17 00:00:00 2001 From: JanLJL Date: Tue, 7 Mar 2023 17:05:31 +0100 Subject: [PATCH 7/7] bugfix, resolved #90 --- osaca/semantics/kernel_dg.py | 4 +--- tests/test_files/kernel_aarch64.s | 1 + tests/test_semantics.py | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/osaca/semantics/kernel_dg.py b/osaca/semantics/kernel_dg.py index 8424177..7ea8fd3 100755 --- a/osaca/semantics/kernel_dg.py +++ b/osaca/semantics/kernel_dg.py @@ -272,9 +272,7 @@ class KernelDG(nx.DiGraph): # print(" TO", instr_form.line, register_changes) if "register" in dst: # read of register - if self.is_read(dst.register, instr_form) and not ( - dst.get("pre_indexed", False) or dst.get("post_indexed", False) - ): + if self.is_read(dst.register, instr_form): yield instr_form, [] # write to register -> abort if self.is_written(dst.register, instr_form): diff --git a/tests/test_files/kernel_aarch64.s b/tests/test_files/kernel_aarch64.s index 7e4b87a..22d2bc7 100644 --- a/tests/test_files/kernel_aarch64.s +++ b/tests/test_files/kernel_aarch64.s @@ -23,3 +23,4 @@ // OSACA-END fmov s1, #2.0e+2f prfm pldl1keep, [x26, #2112] + add x11, x11, x11 diff --git a/tests/test_semantics.py b/tests/test_semantics.py index 35daf47..7d539a9 100755 --- a/tests/test_semantics.py +++ b/tests/test_semantics.py @@ -369,7 +369,7 @@ class TestSemanticTools(unittest.TestCase): self.assertTrue(nx.algorithms.dag.is_directed_acyclic_graph(dg.dg)) self.assertEqual(set(dg.get_dependent_instruction_forms(line_number=3)), {7, 8}) self.assertEqual(set(dg.get_dependent_instruction_forms(line_number=4)), {9, 10}) - self.assertEqual(set(dg.get_dependent_instruction_forms(line_number=5)), {7, 8}) + self.assertEqual(set(dg.get_dependent_instruction_forms(line_number=5)), {6, 7, 8}) self.assertEqual(set(dg.get_dependent_instruction_forms(line_number=6)), {9, 10}) self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=7)), 13) self.assertEqual(next(dg.get_dependent_instruction_forms(line_number=8)), 14) @@ -438,7 +438,7 @@ class TestSemanticTools(unittest.TestCase): self.semantics_tx2, ) lc_deps = dg.get_loopcarried_dependencies() - self.assertEqual(len(lc_deps), 2) + self.assertEqual(len(lc_deps), 4) # based on line 6 self.assertEqual(lc_deps[6]["latency"], 28.0) self.assertEqual(