From b434e30ec12cd502f51ec1bfcbfb199964d9360f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A9cio=20Luiz=20Gazzoni=20Filho?= Date: Sun, 19 Feb 2023 22:08:42 -0300 Subject: [PATCH 1/7] Support for flags and conditional ops on AArch64 --- osaca/data/isa/aarch64.yml | 1833 +++++++++++++++++++++++++++++++- osaca/parser/parser_AArch64.py | 27 +- osaca/semantics/hw_model.py | 2 + 3 files changed, 1857 insertions(+), 5 deletions(-) diff --git a/osaca/data/isa/aarch64.yml b/osaca/data/isa/aarch64.yml index 85246ea..eca5adf 100644 --- a/osaca/data/isa/aarch64.yml +++ b/osaca/data/isa/aarch64.yml @@ -5,7 +5,7 @@ isa: "AArch64" # mnemonic op1 ... opN # means that op1 is the only destination operand and op2 to op(N) are source operands. instruction_forms: - - name: [add, adds] + - name: add operands: - class: register prefix: x @@ -20,7 +20,135 @@ instruction_forms: source: true destination: false operation: "op1['value'] = op2['value'] + op3['value']; op1['name'] = op2['name']" - - name: [sub, subs] + - name: adds + operands: + - class: register + prefix: x + source: false + destination: true + - class: register + prefix: x + source: true + destination: false + - class: register + prefix: x + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + operation: "op1['value'] = op2['value'] + op3['value']; op1['name'] = op2['name']" + - name: adds + operands: + - class: register + prefix: x + source: false + destination: true + - class: register + prefix: x + source: true + destination: false + - class: immediate + imd: 'int' + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + operation: "op1['value'] = op2['value'] + op3['value']; op1['name'] = op2['name']" + - name: adds + operands: + - class: register + prefix: w + source: false + destination: true + - class: register + prefix: w + source: true + destination: false + - class: register + prefix: w + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + operation: "op1['value'] = op2['value'] + op3['value']; op1['name'] = op2['name']" + - name: adds + operands: + - class: register + prefix: w + source: false + destination: true + - class: register + prefix: w + source: true + destination: false + - class: immediate + imd: 'int' + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + operation: "op1['value'] = op2['value'] + op3['value']; op1['name'] = op2['name']" + - name: sub operands: - class: register prefix: x @@ -35,11 +163,632 @@ instruction_forms: source: true destination: false operation: "op1['value'] = op2['value'] - op3['value']; op1['name'] = op2['name']" - - name: [b, bcc, bcs, b.ne, b.any, b.none, b.lt, b.eq, b.hs, b.gt, bne, beq] + - name: subs + operands: + - class: register + prefix: x + source: false + destination: true + - class: register + prefix: x + source: true + destination: false + - class: register + prefix: x + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + operation: "op1['value'] = op2['value'] - op3['value']; op1['name'] = op2['name']" + - name: subs + operands: + - class: register + prefix: x + source: false + destination: true + - class: register + prefix: x + source: true + destination: false + - class: immediate + imd: 'int' + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + operation: "op1['value'] = op2['value'] - op3['value']; op1['name'] = op2['name']" + - name: subs + operands: + - class: register + prefix: w + source: false + destination: true + - class: register + prefix: w + source: true + destination: false + - class: register + prefix: w + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + operation: "op1['value'] = op2['value'] - op3['value']; op1['name'] = op2['name']" + - name: subs + operands: + - class: register + prefix: w + source: false + destination: true + - class: register + prefix: w + source: true + destination: false + - class: immediate + imd: 'int' + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + operation: "op1['value'] = op2['value'] - op3['value']; op1['name'] = op2['name']" + - name: [adcs, sbcs] + operands: + - class: register + prefix: x + source: false + destination: true + - class: register + prefix: x + source: true + destination: false + - class: register + prefix: x + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [adcs, sbcs] + operands: + - class: register + prefix: w + source: false + destination: true + - class: register + prefix: w + source: true + destination: false + - class: register + prefix: w + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: negs + operands: + - class: register + prefix: x + source: false + destination: true + - class: register + prefix: x + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: negs + operands: + - class: register + prefix: w + source: false + destination: true + - class: register + prefix: w + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: ngcs + operands: + - class: register + prefix: x + source: false + destination: true + - class: register + prefix: x + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: ngcs + operands: + - class: register + prefix: w + source: false + destination: true + - class: register + prefix: w + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ands, bics] + operands: + - class: register + prefix: x + source: false + destination: true + - class: register + prefix: x + source: true + destination: false + - class: register + prefix: x + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ands, bics] + operands: + - class: register + prefix: x + source: false + destination: true + - class: register + prefix: x + source: true + destination: false + - class: immediate + imd: 'int' + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ands, bics] + operands: + - class: register + prefix: w + source: false + destination: true + - class: register + prefix: w + source: true + destination: false + - class: register + prefix: w + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ands, bics] + operands: + - class: register + prefix: w + source: false + destination: true + - class: register + prefix: w + source: true + destination: false + - class: immediate + imd: 'int' + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: tst + operands: + - class: register + prefix: x + source: false + destination: true + - class: register + prefix: x + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: tst + operands: + - class: register + prefix: x + source: false + destination: true + - class: immediate + imd: 'int' + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: tst + operands: + - class: register + prefix: w + source: false + destination: true + - class: register + prefix: w + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: tst + operands: + - class: register + prefix: w + source: false + destination: true + - class: immediate + imd: 'int' + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [b, b.any, b.none] operands: - class: identifier source: false destination: false + # - name: [bcc, bcs, b.ne, b.any, b.none, b.lt, b.eq, b.hs, b.gt, bne, beq] + # operands: + # - class: identifier + # source: false + # destination: false + - name: [beq, b.eq, bne, b.ne] + operands: + - class: identifier + source: false + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - name: [bcs, b.cs, bhs, b.hs, bcc, b.cc, blo, b.lo] + operands: + - class: identifier + source: false + destination: false + hidden_operands: + - class: flag + name: "C" + source: true + destination: false + - name: [bhi, b.hi, bls, b.ls] + operands: + - class: identifier + source: false + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "C" + source: true + destination: false + - name: [bge, b.ge, blt, b.lt] + operands: + - class: identifier + source: false + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false + - name: [bgt, b.gt, ble, b.le] + operands: + - class: identifier + source: false + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false + - name: [bmi, b.mi, bpl, b.pl] + operands: + - class: identifier + source: false + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - name: [bvs, b.vs, bvc, b.vc] + operands: + - class: identifier + source: false + destination: false + hidden_operands: + - class: flag + name: "V" + source: true + destination: false - name: [incb, incd] operands: - class: register @@ -190,6 +939,23 @@ instruction_forms: prefix: "*" source: true destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true - name: cmp operands: - class: register @@ -200,6 +966,23 @@ instruction_forms: imd: "int" source: true destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true - name: cmn operands: - class: register @@ -210,6 +993,23 @@ instruction_forms: prefix: "*" source: true destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true - name: cmn operands: - class: register @@ -220,6 +1020,23 @@ instruction_forms: imd: "int" source: true destination: false + hidden_operands: + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true - name: fcmp operands: - class: register @@ -250,3 +1067,1013 @@ instruction_forms: imd: float source: true destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "eq" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "ne" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "cs" + source: true + destination: false + hidden_operands: + - class: flag + name: "C" + source: true + destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "hs" + source: true + destination: false + hidden_operands: + - class: flag + name: "C" + source: true + destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "cc" + source: true + destination: false + hidden_operands: + - class: flag + name: "C" + source: true + destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "lo" + source: true + destination: false + hidden_operands: + - class: flag + name: "C" + source: true + destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "hi" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "C" + source: true + destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "ls" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "C" + source: true + destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "ge" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "lt" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "gt" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "le" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "mi" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "pl" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "vs" + source: true + destination: false + hidden_operands: + - class: flag + name: "V" + source: true + destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + code: "vc" + source: true + destination: false + hidden_operands: + - class: flag + name: "V" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "eq" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "ne" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "cs" + source: true + destination: false + hidden_operands: + - class: flag + name: "C" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "hs" + source: true + destination: false + hidden_operands: + - class: flag + name: "C" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "cc" + source: true + destination: false + hidden_operands: + - class: flag + name: "C" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "lo" + source: true + destination: false + hidden_operands: + - class: flag + name: "C" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "hi" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "C" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "ls" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "C" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "ge" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "lt" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "gt" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "le" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "mi" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "pl" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "vs" + source: true + destination: false + hidden_operands: + - class: flag + name: "V" + source: true + destination: false + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "vc" + source: true + destination: false + hidden_operands: + - class: flag + name: "V" + source: true + destination: false + + + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "eq" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "ne" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "cs" + source: true + destination: false + hidden_operands: + - class: flag + name: "C" + source: true + destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "hs" + source: true + destination: false + hidden_operands: + - class: flag + name: "C" + source: true + destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "cc" + source: true + destination: false + hidden_operands: + - class: flag + name: "C" + source: true + destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "lo" + source: true + destination: false + hidden_operands: + - class: flag + name: "C" + source: true + destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "hi" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "C" + source: true + destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "ls" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "C" + source: true + destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "ge" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "lt" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "gt" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "le" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "mi" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "pl" + source: true + destination: false + hidden_operands: + - class: flag + name: "N" + source: true + destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "vs" + source: true + destination: false + hidden_operands: + - class: flag + name: "V" + source: true + destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: false + destination: true + - class: condition + code: "vc" + source: true + destination: false + hidden_operands: + - class: flag + name: "V" + source: true + destination: false diff --git a/osaca/parser/parser_AArch64.py b/osaca/parser/parser_AArch64.py index 4cf8c78..337f7d1 100755 --- a/osaca/parser/parser_AArch64.py +++ b/osaca/parser/parser_AArch64.py @@ -196,11 +196,34 @@ class ParserAArch64(BaseParser): "policy" ) ).setResultsName("prfop") + # Condition codes + condition = pp.Group( + ( + pp.CaselessLiteral("EQ") + ^ pp.CaselessLiteral("NE") + ^ pp.CaselessLiteral("CS") + ^ pp.CaselessLiteral("HS") + ^ pp.CaselessLiteral("CC") + ^ pp.CaselessLiteral("LO") + ^ pp.CaselessLiteral("HI") + ^ pp.CaselessLiteral("LS") + ^ pp.CaselessLiteral("GE") + ^ pp.CaselessLiteral("LT") + ^ pp.CaselessLiteral("GT") + ^ pp.CaselessLiteral("LE") + ^ pp.CaselessLiteral("MI") + ^ pp.CaselessLiteral("PL") + ^ pp.CaselessLiteral("VS") + ^ pp.CaselessLiteral("VC") + ).setResultsName("code") + ).setResultsName("condition") # Combine to instruction form operand_first = pp.Group( register ^ (prefetch_op | immediate) ^ memory ^ arith_immediate ^ identifier ) - operand_rest = pp.Group((register ^ immediate ^ memory ^ arith_immediate) | identifier) + operand_rest = pp.Group( + (register ^ condition ^ immediate ^ memory ^ arith_immediate) | identifier + ) self.instruction_parser = ( mnemonic + pp.Optional(operand_first.setResultsName("operand1")) @@ -561,7 +584,7 @@ class ParserAArch64(BaseParser): """Check if ``flag_a`` is dependent on ``flag_b``""" # we assume flags are independent of each other, e.g., CF can be read while ZF gets written # TODO validate this assumption - if flag_a.name == flag_b.name: + if flag_a["name"] == flag_b["name"]: return True return False diff --git a/osaca/semantics/hw_model.py b/osaca/semantics/hw_model.py index 15bef95..88468ff 100755 --- a/osaca/semantics/hw_model.py +++ b/osaca/semantics/hw_model.py @@ -581,6 +581,8 @@ class MachineModel(object): # prefetch option if "prfop" in operand: return i_operand["class"] == "prfop" + if "condition" in operand: + return i_operand["class"] == "condition" # no match return False From 1b261912e05d503290622c91662adfc788cd56d9 Mon Sep 17 00:00:00 2001 From: JanLJL Date: Tue, 14 Mar 2023 16:57:34 +0100 Subject: [PATCH 2/7] renamed condition code attrib, fixed incorrect src/dst, and added more conditional instructions --- osaca/data/isa/aarch64.yml | 1517 +++++++++++++++++++++++++++++++++--- 1 file changed, 1399 insertions(+), 118 deletions(-) diff --git a/osaca/data/isa/aarch64.yml b/osaca/data/isa/aarch64.yml index eca5adf..144ef0c 100644 --- a/osaca/data/isa/aarch64.yml +++ b/osaca/data/isa/aarch64.yml @@ -1,4 +1,4 @@ -osaca_version: 0.3.7 +osaca_version: 0.5.0 isa: "AArch64" # Contains all operand-irregular instruction forms OSACA supports for AArch64. # Operand-regular for a AArch64 instruction form with N operands in the shape of @@ -802,14 +802,14 @@ instruction_forms: source: true destination: true - class: identifier - source: false + source: false destination: false - class: identifier - source: false + source: false destination: false - class: immediate imd: int - source: false + source: false destination: false - name: fmla operands: @@ -1078,7 +1078,7 @@ instruction_forms: source: true destination: false - class: condition - code: "eq" + ccode: "eq" source: true destination: false hidden_operands: @@ -1097,7 +1097,7 @@ instruction_forms: source: true destination: false - class: condition - code: "ne" + ccode: "ne" source: true destination: false hidden_operands: @@ -1116,7 +1116,7 @@ instruction_forms: source: true destination: false - class: condition - code: "cs" + ccode: "cs" source: true destination: false hidden_operands: @@ -1135,7 +1135,7 @@ instruction_forms: source: true destination: false - class: condition - code: "hs" + ccode: "hs" source: true destination: false hidden_operands: @@ -1154,7 +1154,7 @@ instruction_forms: source: true destination: false - class: condition - code: "cc" + ccode: "cc" source: true destination: false hidden_operands: @@ -1173,7 +1173,7 @@ instruction_forms: source: true destination: false - class: condition - code: "lo" + ccode: "lo" source: true destination: false hidden_operands: @@ -1192,7 +1192,7 @@ instruction_forms: source: true destination: false - class: condition - code: "hi" + ccode: "hi" source: true destination: false hidden_operands: @@ -1215,7 +1215,7 @@ instruction_forms: source: true destination: false - class: condition - code: "ls" + ccode: "ls" source: true destination: false hidden_operands: @@ -1238,7 +1238,7 @@ instruction_forms: source: true destination: false - class: condition - code: "ge" + ccode: "ge" source: true destination: false hidden_operands: @@ -1261,7 +1261,7 @@ instruction_forms: source: true destination: false - class: condition - code: "lt" + ccode: "lt" source: true destination: false hidden_operands: @@ -1284,7 +1284,7 @@ instruction_forms: source: true destination: false - class: condition - code: "gt" + ccode: "gt" source: true destination: false hidden_operands: @@ -1311,7 +1311,7 @@ instruction_forms: source: true destination: false - class: condition - code: "le" + ccode: "le" source: true destination: false hidden_operands: @@ -1338,7 +1338,7 @@ instruction_forms: source: true destination: false - class: condition - code: "mi" + ccode: "mi" source: true destination: false hidden_operands: @@ -1357,7 +1357,7 @@ instruction_forms: source: true destination: false - class: condition - code: "pl" + ccode: "pl" source: true destination: false hidden_operands: @@ -1376,7 +1376,7 @@ instruction_forms: source: true destination: false - class: condition - code: "vs" + ccode: "vs" source: true destination: false hidden_operands: @@ -1395,7 +1395,7 @@ instruction_forms: source: true destination: false - class: condition - code: "vc" + ccode: "vc" source: true destination: false hidden_operands: @@ -1403,6 +1403,37 @@ instruction_forms: name: "V" source: true destination: false + - name: [cinc, cinv, cneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: condition + ccode: "AL" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "C" + source: true + destination: false + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false - name: [cset, csetm] operands: - class: register @@ -1410,7 +1441,7 @@ instruction_forms: source: false destination: true - class: condition - code: "eq" + ccode: "eq" source: true destination: false hidden_operands: @@ -1425,7 +1456,7 @@ instruction_forms: source: false destination: true - class: condition - code: "ne" + ccode: "ne" source: true destination: false hidden_operands: @@ -1440,7 +1471,7 @@ instruction_forms: source: false destination: true - class: condition - code: "cs" + ccode: "cs" source: true destination: false hidden_operands: @@ -1455,7 +1486,7 @@ instruction_forms: source: false destination: true - class: condition - code: "hs" + ccode: "hs" source: true destination: false hidden_operands: @@ -1470,7 +1501,7 @@ instruction_forms: source: false destination: true - class: condition - code: "cc" + ccode: "cc" source: true destination: false hidden_operands: @@ -1485,7 +1516,7 @@ instruction_forms: source: false destination: true - class: condition - code: "lo" + ccode: "lo" source: true destination: false hidden_operands: @@ -1500,7 +1531,7 @@ instruction_forms: source: false destination: true - class: condition - code: "hi" + ccode: "hi" source: true destination: false hidden_operands: @@ -1519,7 +1550,7 @@ instruction_forms: source: false destination: true - class: condition - code: "ls" + ccode: "ls" source: true destination: false hidden_operands: @@ -1538,7 +1569,7 @@ instruction_forms: source: false destination: true - class: condition - code: "ge" + ccode: "ge" source: true destination: false hidden_operands: @@ -1557,7 +1588,7 @@ instruction_forms: source: false destination: true - class: condition - code: "lt" + ccode: "lt" source: true destination: false hidden_operands: @@ -1576,7 +1607,7 @@ instruction_forms: source: false destination: true - class: condition - code: "gt" + ccode: "gt" source: true destination: false hidden_operands: @@ -1599,7 +1630,7 @@ instruction_forms: source: false destination: true - class: condition - code: "le" + ccode: "le" source: true destination: false hidden_operands: @@ -1622,7 +1653,7 @@ instruction_forms: source: false destination: true - class: condition - code: "mi" + ccode: "mi" source: true destination: false hidden_operands: @@ -1637,7 +1668,7 @@ instruction_forms: source: false destination: true - class: condition - code: "pl" + ccode: "pl" source: true destination: false hidden_operands: @@ -1652,7 +1683,7 @@ instruction_forms: source: false destination: true - class: condition - code: "vs" + ccode: "vs" source: true destination: false hidden_operands: @@ -1667,7 +1698,7 @@ instruction_forms: source: false destination: true - class: condition - code: "vc" + ccode: "vc" source: true destination: false hidden_operands: @@ -1675,8 +1706,33 @@ instruction_forms: name: "V" source: true destination: false - - + - name: [cset, csetm] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: condition + ccode: "AL" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "C" + source: true + destination: false + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false - name: [csel, csinc, csinv, csneg] operands: - class: register @@ -1685,14 +1741,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "eq" + ccode: "eq" source: true destination: false hidden_operands: @@ -1708,14 +1764,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "ne" + ccode: "ne" source: true destination: false hidden_operands: @@ -1731,14 +1787,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "cs" + ccode: "cs" source: true destination: false hidden_operands: @@ -1754,14 +1810,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "hs" + ccode: "hs" source: true destination: false hidden_operands: @@ -1777,14 +1833,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "cc" + ccode: "cc" source: true destination: false hidden_operands: @@ -1800,14 +1856,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "lo" + ccode: "lo" source: true destination: false hidden_operands: @@ -1823,14 +1879,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "hi" + ccode: "hi" source: true destination: false hidden_operands: @@ -1850,14 +1906,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "ls" + ccode: "ls" source: true destination: false hidden_operands: @@ -1877,14 +1933,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "ge" + ccode: "ge" source: true destination: false hidden_operands: @@ -1904,14 +1960,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "lt" + ccode: "lt" source: true destination: false hidden_operands: @@ -1931,14 +1987,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "gt" + ccode: "gt" source: true destination: false hidden_operands: @@ -1962,14 +2018,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "le" + ccode: "le" source: true destination: false hidden_operands: @@ -1993,14 +2049,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "mi" + ccode: "mi" source: true destination: false hidden_operands: @@ -2016,14 +2072,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "pl" + ccode: "pl" source: true destination: false hidden_operands: @@ -2039,14 +2095,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "vs" + ccode: "vs" source: true destination: false hidden_operands: @@ -2062,14 +2118,14 @@ instruction_forms: destination: true - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: register prefix: "*" - source: false - destination: true + source: true + destination: false - class: condition - code: "vc" + ccode: "vc" source: true destination: false hidden_operands: @@ -2077,3 +2133,1228 @@ instruction_forms: name: "V" source: true destination: false + - name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + source: false + destination: true + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: condition + ccode: "AL" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: false + - class: flag + name: "C" + source: true + destination: false + - class: flag + name: "N" + source: true + destination: false + - class: flag + name: "V" + source: true + destination: false + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "EQ" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "NE" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "CS" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "HS" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "CC" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "LO" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "MI" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: true + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "PL" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: true + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "VS" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: true + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "VC" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: true + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "HI" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "LS" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "GE" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: true + destination: true + - class: flag + name: "V" + source: true + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "LT" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: true + destination: true + - class: flag + name: "V" + source: true + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "GT" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: true + destination: true + - class: flag + name: "V" + source: true + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "LE" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: true + destination: true + - class: flag + name: "V" + source: true + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "AL" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "N" + source: true + destination: true + - class: flag + name: "V" + source: true + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "EQ" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "NE" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "CS" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "HS" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "CC" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "LO" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "MI" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: true + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "PL" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: true + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "VS" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: true + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "VC" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: true + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "HI" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "LS" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "N" + source: false + destination: true + - class: flag + name: "V" + source: false + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "GE" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: true + destination: true + - class: flag + name: "V" + source: true + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "LT" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: false + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: true + destination: true + - class: flag + name: "V" + source: true + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "GT" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: true + destination: true + - class: flag + name: "V" + source: true + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "LE" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: true + - class: flag + name: "C" + source: false + destination: true + - class: flag + name: "N" + source: true + destination: true + - class: flag + name: "V" + source: true + destination: true + - name: [ccmn, ccmp] + operands: + - class: register + prefix: "*" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: immediate + imd: "int" + source: true + destination: false + - class: condition + ccode: "AL" + source: true + destination: false + hidden_operands: + - class: flag + name: "Z" + source: true + destination: true + - class: flag + name: "C" + source: true + destination: true + - class: flag + name: "N" + source: true + destination: true + - class: flag + name: "V" + source: true + destination: true From 0985e81b23712993dad78df9343925bcec94e8f9 Mon Sep 17 00:00:00 2001 From: JanLJL Date: Tue, 14 Mar 2023 17:00:02 +0100 Subject: [PATCH 3/7] added more dependency analysis for post/pre indexing and condition flags --- osaca/frontend.py | 4 +- osaca/parser/parser_AArch64.py | 40 ++++++++-------- osaca/semantics/hw_model.py | 9 +++- osaca/semantics/isa_semantics.py | 1 - osaca/semantics/kernel_dg.py | 37 ++++++++++----- tests/test_files/kernel_aarch64_deps.s | 14 ++++++ tests/test_parser_AArch64.py | 37 +++++++++++++++ tests/test_semantics.py | 66 +++++++++++++++++++++----- 8 files changed, 161 insertions(+), 47 deletions(-) create mode 100644 tests/test_files/kernel_aarch64_deps.s diff --git a/osaca/frontend.py b/osaca/frontend.py index 9a1fa2f..19814c3 100755 --- a/osaca/frontend.py +++ b/osaca/frontend.py @@ -144,9 +144,9 @@ class Frontend(object): + "-----------------------------------------\n" ) # TODO find a way to overcome padding for different tab-lengths - for dep in dep_dict: + for dep in sorted(dep_dict.keys()): s += "{:4d} {} {:4.1f} {} {:36}{} {}\n".format( - dep, + int(dep.split("-")[0]), separator, dep_dict[dep]["latency"], separator, diff --git a/osaca/parser/parser_AArch64.py b/osaca/parser/parser_AArch64.py index 337f7d1..fec3261 100755 --- a/osaca/parser/parser_AArch64.py +++ b/osaca/parser/parser_AArch64.py @@ -196,27 +196,27 @@ class ParserAArch64(BaseParser): "policy" ) ).setResultsName("prfop") - # Condition codes - condition = pp.Group( - ( - pp.CaselessLiteral("EQ") - ^ pp.CaselessLiteral("NE") - ^ pp.CaselessLiteral("CS") - ^ pp.CaselessLiteral("HS") - ^ pp.CaselessLiteral("CC") - ^ pp.CaselessLiteral("LO") - ^ pp.CaselessLiteral("HI") - ^ pp.CaselessLiteral("LS") - ^ pp.CaselessLiteral("GE") - ^ pp.CaselessLiteral("LT") - ^ pp.CaselessLiteral("GT") - ^ pp.CaselessLiteral("LE") - ^ pp.CaselessLiteral("MI") - ^ pp.CaselessLiteral("PL") - ^ pp.CaselessLiteral("VS") - ^ pp.CaselessLiteral("VC") - ).setResultsName("code") + # Condition codes, based on http://tiny.cc/armcc + condition = ( + pp.CaselessLiteral("EQ") # z set + ^ pp.CaselessLiteral("NE") # z clear + ^ pp.CaselessLiteral("CS") # c set + ^ pp.CaselessLiteral("HS") # c set + ^ pp.CaselessLiteral("CC") # c clear + ^ pp.CaselessLiteral("LO") # c clear + ^ pp.CaselessLiteral("MI") # n set + ^ pp.CaselessLiteral("PL") # n clear + ^ pp.CaselessLiteral("VS") # v set + ^ pp.CaselessLiteral("VC") # v clear + ^ pp.CaselessLiteral("HI") # c set and z clear + ^ pp.CaselessLiteral("LS") # c clear or z set + ^ pp.CaselessLiteral("GE") # n and v the same + ^ pp.CaselessLiteral("LT") # n and v different + ^ pp.CaselessLiteral("GT") # z clear, and n and v the same + ^ pp.CaselessLiteral("LE") # z set, or n and v different + ^ pp.CaselessLiteral("AL") # any ).setResultsName("condition") + self.condition = condition # Combine to instruction form operand_first = pp.Group( register ^ (prefetch_op | immediate) ^ memory ^ arith_immediate ^ identifier diff --git a/osaca/semantics/hw_model.py b/osaca/semantics/hw_model.py index 88468ff..dbbfdf3 100755 --- a/osaca/semantics/hw_model.py +++ b/osaca/semantics/hw_model.py @@ -581,8 +581,15 @@ class MachineModel(object): # prefetch option if "prfop" in operand: return i_operand["class"] == "prfop" + # condition if "condition" in operand: - return i_operand["class"] == "condition" + if i_operand["ccode"] == self.WILDCARD: + return True + return i_operand["class"] == "condition" and ( + operand.get("condition", None) == i_operand.get("ccode", None).upper() + if isinstance(i_operand.get("ccode", None), str) + else i_operand.get("ccode", None) + ) # no match return False diff --git a/osaca/semantics/isa_semantics.py b/osaca/semantics/isa_semantics.py index fca5955..6d523a7 100755 --- a/osaca/semantics/isa_semantics.py +++ b/osaca/semantics/isa_semantics.py @@ -127,7 +127,6 @@ class ISASemantics(object): } ) ) - # store operand list in dict and reassign operand key/value pair instruction_form["semantic_operands"] = AttrDict.convert_dict(op_dict) # assign LD/ST flags diff --git a/osaca/semantics/kernel_dg.py b/osaca/semantics/kernel_dg.py index 8424177..a21beac 100755 --- a/osaca/semantics/kernel_dg.py +++ b/osaca/semantics/kernel_dg.py @@ -22,14 +22,17 @@ class KernelDG(nx.DiGraph): hw_model: MachineModel, semantics: ArchSemantics, timeout=10, + flag_dependencies=False, ): self.timed_out = False self.kernel = parsed_kernel self.parser = parser self.model = hw_model self.arch_sem = semantics - self.dg = self.create_DG(self.kernel) - self.loopcarried_deps = self.check_for_loopcarried_dep(self.kernel, timeout) + self.dg = self.create_DG(self.kernel, flag_dependencies) + self.loopcarried_deps = self.check_for_loopcarried_dep( + self.kernel, timeout, flag_dependencies + ) def _extend_path(self, dst_list, kernel, dg, offset): for instr in kernel: @@ -40,12 +43,15 @@ class KernelDG(nx.DiGraph): dst_list.extend(tmp_list) # print('Thread [{}-{}] done'.format(kernel[0]['line_number'], kernel[-1]['line_number'])) - def create_DG(self, kernel): + def create_DG(self, kernel, flag_dependencies=False): """ Create directed graph from given kernel :param kernel: Parsed asm kernel with assigned semantic information :type kerne: list + :param flag_dependencies: indicating if dependencies of flags should be considered, + defaults to `False` + :type flag_dependencies: boolean, optional :returns: :class:`~nx.DiGraph` -- directed graph object """ # 1. go through kernel instruction forms and add them as node attribute @@ -71,23 +77,28 @@ class KernelDG(nx.DiGraph): instruction_form["line_number"], latency=instruction_form["latency"] - instruction_form["latency_wo_load"], ) - for dep, dep_flags in self.find_depending(instruction_form, kernel[i + 1 :]): + for dep, dep_flags in self.find_depending( + instruction_form, kernel[i + 1 :], flag_dependencies + ): edge_weight = ( instruction_form["latency"] if "mem_dep" in dep_flags or "latency_wo_load" not in instruction_form else instruction_form["latency_wo_load"] ) - if "storeload_dep" in dep_flags: + if "storeload_dep" in dep_flags and self.model is not None: edge_weight += self.model.get("store_to_load_forward_latency", 0) + if "p_indexed" in dep_flags and self.model is not None: + edge_weight = self.model.get("p_index_latency", 1) dg.add_edge( instruction_form["line_number"], dep["line_number"], latency=edge_weight, ) + dg.nodes[dep["line_number"]]["instruction_form"] = dep return dg - def check_for_loopcarried_dep(self, kernel, timeout=10): + def check_for_loopcarried_dep(self, kernel, timeout=10, flag_dependencies=False): """ Try to find loop-carried dependencies in given kernel. @@ -106,7 +117,7 @@ class KernelDG(nx.DiGraph): temp_iform["line_number"] += offset tmp_kernel.append(temp_iform) # get dependency graph - dg = self.create_DG(tmp_kernel) + dg = self.create_DG(tmp_kernel, flag_dependencies) # build cyclic loop-carried dependencies loopcarried_deps = [] @@ -191,7 +202,8 @@ class KernelDG(nx.DiGraph): # map lcd back to nodes loopcarried_deps_dict = {} for lat_sum, involved_lines in loopcarried_deps: - loopcarried_deps_dict[involved_lines[0][0]] = { + dict_key = "-".join([str(il[0]) for il in involved_lines]) + loopcarried_deps_dict[dict_key] = { "root": self._get_node_by_lineno(involved_lines[0][0]), "dependencies": [ (self._get_node_by_lineno(ln), lat) for ln, lat in involved_lines @@ -272,10 +284,11 @@ 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) - ): - yield instr_form, [] + if self.is_read(dst.register, instr_form): + if dst.get("pre_indexed", False) or dst.get("post_indexed", False): + yield instr_form, ["p_indexed"] + else: + yield instr_form, [] # write to register -> abort if self.is_written(dst.register, instr_form): break diff --git a/tests/test_files/kernel_aarch64_deps.s b/tests/test_files/kernel_aarch64_deps.s new file mode 100644 index 0000000..ee4848f --- /dev/null +++ b/tests/test_files/kernel_aarch64_deps.s @@ -0,0 +1,14 @@ +// OSACA-BEGIN +.LBB0_32: + ldp q4, q5, [x9, #-32] + ldp q6, q7, [x9], #64 + add x9, x9, x9 + add x10, x9, #64 // =64 + fmul v4.2d, v4.2d, v6.2d + fmul v5.2d, v4.2d, v7.2d + adds x10, x10, x10 + csel, x9, x1, x9, eq + stp q14, q15, [x9, #-32]! + stp q14, q15, [x9], #64 + b.ne .LBB0_32 +// OSACA-END diff --git a/tests/test_parser_AArch64.py b/tests/test_parser_AArch64.py index fdcf7f1..ba11504 100755 --- a/tests/test_parser_AArch64.py +++ b/tests/test_parser_AArch64.py @@ -73,6 +73,14 @@ class TestParserAArch64(unittest.TestCase): "IACA START", ) + def test_condition_parser(self): + self.assertEqual(self._get_condition(self.parser, "EQ"), "EQ") + self.assertEqual(self._get_condition(self.parser, "ne"), "NE") + self.assertEqual(self._get_condition(self.parser, "Lt"), "LT") + self.assertEqual(self._get_condition(self.parser, "Gt"), "GT") + with self.assertRaises(ParseException): + self._get_condition(self.parser, "LOcondition") + def test_parse_instruction(self): instr1 = "\t\tvcvt.F32.S32 w1, w2\t\t\t//12.27" instr2 = "b.lo ..B1.4 \t" @@ -81,6 +89,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 = "ccmp x0, x1, #4, cc" parsed_1 = self.parser.parse_instruction(instr1) parsed_2 = self.parser.parse_instruction(instr2) @@ -89,6 +98,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 +152,11 @@ 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, "ccmp") + self.assertEqual(parsed_8.operands[0].register.name, "0") + self.assertEqual(parsed_8.operands[0].register.prefix, "x") + self.assertEqual(parsed_8.operands[3].condition, "CC") + def test_parse_line(self): line_comment = "// -- Begin main" line_label = ".LBB0_1: // =>This Inner Loop Header: Depth=1" @@ -151,6 +166,7 @@ class TestParserAArch64(unittest.TestCase): line_preindexed = "stp x29, x30, [sp, #-16]!" line_postindexed = "ldp q2, q3, [x11], #64" line_5_operands = "fcmla z26.d, p0/m, z29.d, z21.d, #90" + line_conditions = "ccmn x11, #1, #3, eq" instruction_form_1 = { "instruction": None, @@ -281,6 +297,20 @@ class TestParserAArch64(unittest.TestCase): "line": "fcmla z26.d, p0/m, z29.d, z21.d, #90", "line_number": 8, } + instruction_form_9 = { + "instruction": "ccmn", + "operands": [ + {"register": {"prefix": "x", "name": "11"}}, + {"immediate": {"value": 1, "type": "int"}}, + {"immediate": {"value": 3, "type": "int"}}, + {"condition": "EQ"} + ], + "directive": None, + "comment": None, + "label": None, + "line": "ccmn x11, #1, #3, eq", + "line_number": 9, + } parsed_1 = self.parser.parse_line(line_comment, 1) parsed_2 = self.parser.parse_line(line_label, 2) @@ -290,6 +320,7 @@ class TestParserAArch64(unittest.TestCase): parsed_6 = self.parser.parse_line(line_preindexed, 6) parsed_7 = self.parser.parse_line(line_postindexed, 7) parsed_8 = self.parser.parse_line(line_5_operands, 8) + parsed_9 = self.parser.parse_line(line_conditions, 9) self.assertEqual(parsed_1, instruction_form_1) self.assertEqual(parsed_2, instruction_form_2) @@ -299,6 +330,7 @@ class TestParserAArch64(unittest.TestCase): self.assertEqual(parsed_6, instruction_form_6) self.assertEqual(parsed_7, instruction_form_7) self.assertEqual(parsed_8, instruction_form_8) + self.assertEqual(parsed_9, instruction_form_9) def test_parse_file(self): parsed = self.parser.parse_file(self.triad_code) @@ -425,6 +457,11 @@ class TestParserAArch64(unittest.TestCase): parser.process_operand(parser.directive.parseString(directive, parseAll=True).asDict()) ).directive + def _get_condition(self, parser, condition): + return AttrDict.convert_dict( + parser.process_operand(parser.condition.parseString(condition, parseAll=True).asDict()) + ).condition + @staticmethod def _find_file(name): testdir = os.path.dirname(__file__) diff --git a/tests/test_semantics.py b/tests/test_semantics.py index 327f173..f044a00 100755 --- a/tests/test_semantics.py +++ b/tests/test_semantics.py @@ -43,6 +43,8 @@ class TestSemanticTools(unittest.TestCase): cls.code_AArch64 = f.read() with open(cls._find_file("kernel_aarch64_sve.s")) as f: cls.code_AArch64_SVE = f.read() + with open(cls._find_file("kernel_aarch64_deps.s")) as f: + cls.code_AArch64_deps = f.read() cls.kernel_x86 = reduce_to_section(cls.parser_x86.parse_file(cls.code_x86), "x86") cls.kernel_x86_memdep = reduce_to_section( cls.parser_x86.parse_file(cls.code_x86_memdep), "x86" @@ -59,6 +61,9 @@ class TestSemanticTools(unittest.TestCase): cls.kernel_aarch64_SVE = reduce_to_section( cls.parser_AArch64.parse_file(cls.code_AArch64_SVE), "aarch64" ) + cls.kernel_aarch64_deps = reduce_to_section( + cls.parser_AArch64.parse_file(cls.code_AArch64_deps), "aarch64" + ) # set up machine models cls.machine_model_csx = MachineModel( @@ -104,6 +109,9 @@ class TestSemanticTools(unittest.TestCase): for i in range(len(cls.kernel_aarch64_SVE)): cls.semantics_a64fx.assign_src_dst(cls.kernel_aarch64_SVE[i]) cls.semantics_a64fx.assign_tp_lt(cls.kernel_aarch64_SVE[i]) + for i in range(len(cls.kernel_aarch64_deps)): + cls.semantics_a64fx.assign_src_dst(cls.kernel_aarch64_deps[i]) + cls.semantics_a64fx.assign_tp_lt(cls.kernel_aarch64_deps[i]) ########### # Tests @@ -365,7 +373,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) @@ -434,40 +442,76 @@ 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) + dep_path = "6-10-11-12-13-14" + self.assertEqual(lc_deps[dep_path]["latency"], 29.0) self.assertEqual( - [(iform.line_number, lat) for iform, lat in lc_deps[6]["dependencies"]], - [(6, 4.0), (10, 6.0), (11, 6.0), (12, 6.0), (13, 6.0), (14, 0)], + [ + (iform.line_number, lat) + for iform, lat in lc_deps[dep_path]["dependencies"] + ], + [(6, 4.0), (10, 6.0), (11, 6.0), (12, 6.0), (13, 6.0), (14, 1.0)], + ) + dg = KernelDG( + self.kernel_aarch64_deps, + self.parser_AArch64, + self.machine_model_a64fx, + self.semantics_a64fx, + flag_dependencies=True, + ) + lc_deps = dg.get_loopcarried_dependencies() + self.assertEqual(len(lc_deps), 2) + # based on line 4 + dep_path = "4-5-6-9-10-11-12" + self.assertEqual(lc_deps[dep_path]["latency"], 7.0) + self.assertEqual( + [(iform.line_number, lat) for iform, lat in lc_deps[dep_path]["dependencies"]], + [(4, 1.0), (5, 1.0), (6, 1.0), (9, 1.0), (10, 1.0), (11, 1.0), (12, 1.0)], + ) + dg = KernelDG( + self.kernel_aarch64_deps, + self.parser_AArch64, + self.machine_model_a64fx, + self.semantics_a64fx, + flag_dependencies=False, + ) + lc_deps = dg.get_loopcarried_dependencies() + self.assertEqual(len(lc_deps), 1) + # based on line 4 + dep_path = "4-5-10-11-12" + self.assertEqual(lc_deps[dep_path]["latency"], 5.0) + self.assertEqual( + [(iform.line_number, lat) for iform, lat in lc_deps[dep_path]["dependencies"]], + [(4, 1.0), (5, 1.0), (10, 1.0), (11, 1.0), (12, 1.0)], ) def test_loop_carried_dependency_x86(self): - lcd_id = 8 - lcd_id2 = 5 + lcd_id = "8" + lcd_id2 = "5" dg = KernelDG(self.kernel_x86, self.parser_x86, self.machine_model_csx, self.semantics_csx) lc_deps = dg.get_loopcarried_dependencies() self.assertEqual(len(lc_deps), 2) # ID 8 self.assertEqual( - lc_deps[lcd_id]["root"], dg.dg.nodes(data=True)[lcd_id]["instruction_form"] + lc_deps[lcd_id]["root"], dg.dg.nodes(data=True)[int(lcd_id)]["instruction_form"] ) self.assertEqual(len(lc_deps[lcd_id]["dependencies"]), 1) self.assertEqual( lc_deps[lcd_id]["dependencies"][0][0], - dg.dg.nodes(data=True)[lcd_id]["instruction_form"], + dg.dg.nodes(data=True)[int(lcd_id)]["instruction_form"], ) # w/ flag dependencies: ID 9 w/ len=2 # w/o flag dependencies: ID 5 w/ len=1 # TODO discuss self.assertEqual( lc_deps[lcd_id2]["root"], - dg.dg.nodes(data=True)[lcd_id2]["instruction_form"], + dg.dg.nodes(data=True)[int(lcd_id2)]["instruction_form"], ) self.assertEqual(len(lc_deps[lcd_id2]["dependencies"]), 1) self.assertEqual( lc_deps[lcd_id2]["dependencies"][0][0], - dg.dg.nodes(data=True)[lcd_id2]["instruction_form"], + dg.dg.nodes(data=True)[int(lcd_id2)]["instruction_form"], ) def test_timeout_during_loop_carried_dependency(self): From 7c6de89f3019a1c448d2e541ccd27b1ffe376835 Mon Sep 17 00:00:00 2001 From: JanLJL Date: Tue, 14 Mar 2023 17:00:23 +0100 Subject: [PATCH 4/7] more instructions --- osaca/data/a64fx.yml | 74 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 11 deletions(-) diff --git a/osaca/data/a64fx.yml b/osaca/data/a64fx.yml index 4560e84..8f35c75 100644 --- a/osaca/data/a64fx.yml +++ b/osaca/data/a64fx.yml @@ -1,4 +1,4 @@ -osaca_version: 0.3.3 +osaca_version: 0.5.0 micro_architecture: Fujitsu A64FX arch_code: a64fx isa: AArch64 @@ -25,6 +25,7 @@ load_throughput: load_throughput_default: [[1, '56'], [1, ['5D', '6D']]] store_throughput: [] store_throughput_default: [[1, '5'], [1, '6']] +p_index_latency: 1 #store_throughput_multiplier: {w: 1.0, x: 1.0, b: 1.0, h: 1.0, s: 1.0, d: 1.0, q: 1.0, v: 2.0, z: 2.0} ports: ['0', 0DV, '1', '2', '3', '4', '5', 5D, '6', 6D, '7'] port_model_scheme: | @@ -356,27 +357,62 @@ instruction_forms: throughput: 0.5 latency: 1.0 # 1*p34 port_pressure: [[1, '34']] -- name: csel +- name: [ccmp, ccmn] operands: - class: register - prefix: x + prefix: "*" + - class: immediate + imd: int + - class: immediate + imd: int + - class: condition + ccode: "*" + throughput: 1.0 + latency: 2.0 # 2*p3 | 2*p4 + port_pressure: [[2, '34']] +- name: [ccmp, ccmn] + operands: - class: register - prefix: x + prefix: "*" - class: register - prefix: x - - class: identifier + prefix: "*" + - class: immediate + imd: int + - class: condition + ccode: "*" + throughput: 1.0 + latency: 2.0 # 2*p3 | 2*p4 + port_pressure: [[2, '34']] +- name: [csel, csinc, csinv, csneg] + operands: + - class: register + prefix: "*" + - class: register + prefix: "*" + - class: register + prefix: "*" + - class: condition + ccode: "*" throughput: 0.5 latency: 1.0 # 1*p34 port_pressure: [[1, '34']] -- name: csel +- name: [cinc, cinv, cneg] operands: - class: register - prefix: w + prefix: "*" - class: register - prefix: w + prefix: "*" + - class: condition + ccode: "*" + throughput: 0.5 + latency: 1.0 # 1*p34 + port_pressure: [[1, '34']] +- name: [cset, csetm] + operands: - class: register - prefix: w - - class: identifier + prefix: "*" + - class: condition + ccode: "*" throughput: 0.5 latency: 1.0 # 1*p34 port_pressure: [[1, '34']] @@ -2152,6 +2188,22 @@ instruction_forms: throughput: 2.0 latency: 0 # 2*p56+2*p0 port_pressure: [[2, '5'], [2,'6'], [2, '0']] +- name: stp + operands: + - class: register + prefix: q + - class: register + prefix: q + - class: memory + base: x + offset: '*' + index: '*' + scale: '*' + pre-indexed: true + post-indexed: false + throughput: 2.0 + latency: 0 # 2*p56+2*p0+1*0234 + port_pressure: [[2, '5'], [2,'6'], [2, '0'], [1, '0234']] - name: stp operands: - class: register From 71b425c1de7b3e1991650a94bdbd478b0b7e52ac Mon Sep 17 00:00:00 2001 From: JanLJL Date: Tue, 14 Mar 2023 17:00:49 +0100 Subject: [PATCH 5/7] added support for optional condition flag dependency analysis --- osaca/osaca.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/osaca/osaca.py b/osaca/osaca.py index 8ef44d3..f5f9bcf 100755 --- a/osaca/osaca.py +++ b/osaca/osaca.py @@ -170,6 +170,14 @@ def create_parser(parser=None): " its analysis with the dependency paths found up to this point. Defaults to 10." " Set to -1 for no timeout.", ) + parser.add_argument( + "--consider-flag-deps", + "-f", + dest="consider_flag_deps", + action="store_true", + default=False, + help="Consider flag dependencies (carry, zero, ...)", + ) parser.add_argument( "--verbose", "-v", action="count", default=0, help="Increases verbosity level." ) @@ -333,7 +341,9 @@ def inspect(args, output_file=sys.stdout): semantics.assign_optimal_throughput(kernel) # Create DiGrahps - kernel_graph = KernelDG(kernel, parser, machine_model, semantics, args.lcd_timeout) + kernel_graph = KernelDG( + kernel, parser, machine_model, semantics, args.lcd_timeout, args.consider_flag_deps + ) if args.dotpath is not None: kernel_graph.export_graph(args.dotpath if args.dotpath != "." else None) # Print analysis From 1f010ecf7e614a9c04f80c758fe2c624d94de200 Mon Sep 17 00:00:00 2001 From: JanLJL Date: Tue, 14 Mar 2023 17:51:20 +0100 Subject: [PATCH 6/7] add missing instruction for test --- 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 a1a6d48..f99cbcb 100644 --- a/osaca/data/a64fx.yml +++ b/osaca/data/a64fx.yml @@ -187,14 +187,25 @@ instruction_forms: - name: adds operands: - class: register - prefix: x + prefix: "*" - class: register - prefix: x + prefix: "*" - class: immediate imd: int throughput: 0.5 latency: 1.0 # 1*p34 port_pressure: [[1, '34']] +- name: adds + operands: + - class: register + prefix: "*" + - class: register + prefix: "*" + - class: register + prefix: "*" + throughput: 0.5 + latency: 1.0 # 1*p34 + port_pressure: [[1, '34']] - name: and operands: - class: register From 261039e51ea358d68288a0074d9795c43827294b Mon Sep 17 00:00:00 2001 From: JanLJL Date: Tue, 14 Mar 2023 18:22:27 +0100 Subject: [PATCH 7/7] black-compliant formatting --- osaca/parser/parser_AArch64.py | 2 +- tests/test_parser_AArch64.py | 2 +- tests/test_semantics.py | 5 +---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/osaca/parser/parser_AArch64.py b/osaca/parser/parser_AArch64.py index 439ddbc..30dd9d6 100755 --- a/osaca/parser/parser_AArch64.py +++ b/osaca/parser/parser_AArch64.py @@ -198,7 +198,7 @@ class ParserAArch64(BaseParser): ).setResultsName("prfop") # Condition codes, based on http://tiny.cc/armcc condition = ( - pp.CaselessLiteral("EQ") # z set + pp.CaselessLiteral("EQ") # z set ^ pp.CaselessLiteral("NE") # z clear ^ pp.CaselessLiteral("CS") # c set ^ pp.CaselessLiteral("HS") # c set diff --git a/tests/test_parser_AArch64.py b/tests/test_parser_AArch64.py index 0bac579..c9ffc76 100755 --- a/tests/test_parser_AArch64.py +++ b/tests/test_parser_AArch64.py @@ -313,7 +313,7 @@ class TestParserAArch64(unittest.TestCase): {"register": {"prefix": "x", "name": "11"}}, {"immediate": {"value": 1, "type": "int"}}, {"immediate": {"value": 3, "type": "int"}}, - {"condition": "EQ"} + {"condition": "EQ"}, ], "directive": None, "comment": None, diff --git a/tests/test_semantics.py b/tests/test_semantics.py index 48247a0..1d22750 100755 --- a/tests/test_semantics.py +++ b/tests/test_semantics.py @@ -451,10 +451,7 @@ class TestSemanticTools(unittest.TestCase): dep_path = "6-10-11-12-13-14" self.assertEqual(lc_deps[dep_path]["latency"], 29.0) self.assertEqual( - [ - (iform.line_number, lat) - for iform, lat in lc_deps[dep_path]["dependencies"] - ], + [(iform.line_number, lat) for iform, lat in lc_deps[dep_path]["dependencies"]], [(6, 4.0), (10, 6.0), (11, 6.0), (12, 6.0), (13, 6.0), (14, 1.0)], ) dg = KernelDG(